Skip to main content

RFC reference

lthn.ai Platform RFC

> The authoritative spec for the lthn.ai platform. > An agent should be able to implement any feature from this document alone.

doc/RFC.md

lthn.ai Platform RFC

The authoritative spec for the lthn.ai platform. An agent should be able to implement any feature from this document alone.

Status: Draft specification, implementation baseline verified in-repo on 2026-03-31 Repository: /Users/snider/Code/lab/lthn.ai Framework: CorePHP modular monolith Production: lthn.ai (de1) Staging: lthn.sh (homelab 10.69.69.165) Local: lthn.test

Implementation snapshot (2026-03-31): OpenBrain async indexing and discovery, agent context boot, recall feedback, lifecycle pruning, workspace hierarchy APIs, Forge dashboard, fleet dispatch, agent OAuth, upgrade guides, docs search, webhook ingress, self-monitoring snapshots, and MCP operator surfaces are implemented in the current repo and covered by the local test suite.


1. Platform Overview

lthn.ai is the production platform for the Lethean ecosystem. It provides:

  • Agent coordination — dispatch, messaging, brain (semantic memory)
  • AI services — LEM model management, ethical scoring, studio (image/voice/remix)
  • Infrastructure — MCP portal, server monitoring, documentation
  • Commerce — subscriptions, API keys, usage billing

1.1 Domain Map

Domain Website Module Purpose
lthn.ai Website\Lthn Marketing, models, ethics, research
app.lthn.ai Website\App Client dashboard (authenticated)
api.lthn.ai Website\Api REST API + MCP HTTP bridge
mcp.lthn.ai Website\Mcp MCP server registry + portal
docs.lthn.ai Website\Docs Documentation

1.2 Module Map

Module Namespace Purpose
Agentic Mod\Agentic Agent dispatch, messaging, plans, sessions
Lem Mod\Lem LEM model management, ethical scoring
Mcp Mod\Mcp MCP tool/server registry
Studio Mod\Studio Multimedia pipeline (image, voice, remix)
Uptelligence Mod\Uptelligence Server monitoring, uptime

1.3 Service Map

Service Namespace Purpose
Commerce Service\Commerce Subscriptions, billing, API keys
Agentic Service\Agentic Agent service definitions + entitlements

2. Infrastructure

2.1 Stack

Component Production (de1) Homelab (lthn.sh) Local (lthn.test)
App Docker 8005-8006 Docker Valet/Herd
Database MariaDB (Galera) MariaDB MariaDB
Cache Dragonfly (6379) Redis Redis
Search Elasticsearch Elasticsearch Elasticsearch
Vector Qdrant (qdrant.lthn.sh) Qdrant Qdrant
Embedding Ollama (homelab) Ollama (local) Ollama
Queue Redis Redis sync
Storage Garage S3 (3900) Local Local
Auth Authentik (9000) - -
Proxy Traefik (80/443) Traefik -

2.2 Deployment

# Production (de1) — ALWAYS via Ansible
cd ~/Code/DevOps
ansible-playbook playbooks/deploy_lthn_ai.yml -i inventory/linux_snider_dev.yml

# Homelab (lthn.sh)
ansible-playbook playbooks/deploy_lthn_sh.yml -i inventory/linux_snider_dev.yml

# NEVER ssh directly to production (port 22 = endlessh trap, real SSH on 4819)

3. OpenBrain — Semantic Memory

See doc/RFC-OPENBRAIN.md for the full spec.

Summary:

  • MariaDB is source of truth (text + metadata)
  • Qdrant is the vector index (embeddings + payload)
  • Elasticsearch for full-text search + tag discovery
  • Async embedding via queue jobs (return fast, index later)
  • Scoped by {org}/{project} — "core/go-io", "lthn/lthn.ai", "ofm/ofm.bot"
  • Re-index command rebuilds Qdrant/ES from MariaDB

3.1 Current State

  • BrainService exists at Core\Mod\Agentic\Services\BrainService
  • API routes at api.lthn.ai/v1/brain/*
  • MariaDB, Qdrant, and Elasticsearch-backed discovery are wired
  • Embedding is queued asynchronously via EmbedMemory
  • Org and project scoping are persisted in MariaDB and Qdrant payloads
  • Discovery endpoints cover search, tags, and scopes
  • Maintenance commands cover re-indexing and content cleanup
  • 8,654 memories in production

3.2 What Needs Doing

  1. Backfill and operate production indexes during rollout
  2. Track live queue depth and indexing latency in Uptelligence
  3. Verify rate limits and failure handling against production traffic
  4. Keep discovery relevance tuned as production memory volume grows

4. Workspace Hierarchy

Core-tenant currently has flat workspaces. Need child workspaces for project organisation.

4.1 Schema

workspaces
├── id
├── parent_id      ← NEW (nullable, self-referencing FK)
├── name
├── slug
├── owner_id
├── plan_id
└── settings (JSON)

Example:
  Workspace "Core" (id=1, parent_id=null)
    ├── Child "go-io" (id=10, parent_id=1)
    ├── Child "agent" (id=11, parent_id=1)
    └── Child "mcp" (id=12, parent_id=1)
  Workspace "OFM" (id=2, parent_id=null)
    └── Child "ofm.bot" (id=20, parent_id=2)

4.2 Inheritance

  • Child workspaces inherit parent's users and entitlements
  • Child can have additional members (project-specific collaborators)
  • Billing rolls up to parent workspace
  • Each child gets its own API key scope

4.3 Admin Panel

Project overview in core-admin showing:

  • Workspace tree (parent → children)
  • Per-project stats (memories, agents, API calls)
  • Quick navigation to project settings

5. API

5.1 Current Endpoints

Prefix Module Status
/v1/brain/* OpenBrain Working (async indexing + scoped discovery)
/v1/messages/* Agent Messaging Working
/v1/plans/* Plans Working
/v1/sessions/* Sessions Working
/v1/score/* EaaS Scoring Working
/v1/health Health Working
/mcp/* MCP Bridge Working
/v1/docs/search Docs search Working
/v1/upgrades/* Upgrade guides Working
/v1/agent/* Fleet registration, check-in, SSE Working
/oauth/token Agent OAuth client credentials Working
/docs/* OpenAPI Working

5.2 Implemented RFC Endpoints

Endpoint Purpose Status
GET /v1/brain/search Elasticsearch full-text search Implemented
GET /v1/brain/tags Tag discovery/aggregation Implemented
GET /v1/brain/scopes List orgs/projects with counts Implemented
GET /v1/brain/agent/{agent_id}/context Agent boot context across agent/shared/project/session scopes Implemented
POST /v1/brain/recall/{recall_id}/feedback Recall quality feedback loop Implemented
GET /v1/workspaces/{id}/children Child workspace listing Implemented
POST /v1/workspaces/{id}/children Create child workspace Implemented
POST /v1/agent/register Fleet agent registration Implemented
GET /v1/agent/checkin Agent polling fallback Implemented
GET /v1/agent/events Fleet SSE stream Implemented
GET /v1/issues/* Forge issue proxy Implemented
GET /v1/upgrades/* Upgrade guide API surface Implemented

5.3 Auth

API keys with scope-based permissions:

  • brain:read / brain:write
  • plans:read / plans:write
  • sessions:read / sessions:write
  • score:read / score:write

6. Testing

6.1 Current State

  • RFC coverage has been expanded across API, Agentic, MCP, Uptelligence, Forge, Docs, and LEM surfaces
  • The local suite passes with 173 tests and 790 assertions as of 2026-03-31
  • Remaining work is operational coverage and production verification, not missing baseline tests

6.2 Required

Every API endpoint needs:

  • Happy path test (valid request → expected response)
  • Auth test (no token → 401, wrong scope → 403)
  • Validation test (bad input → 422)
  • Edge case test (empty results, max limits, etc.)

Every Service needs:

  • Unit tests with mocked dependencies
  • Integration tests against real DB

6.3 Convention

// Test naming: descriptive, grouped by endpoint
class BrainRecallTest extends TestCase
{
    public function test_recall_returns_ranked_memories(): void { }
    public function test_recall_filters_by_org(): void { }
    public function test_recall_requires_auth(): void { }
    public function test_recall_validates_query(): void { }
}

7. UI

7.1 Stack

  • Livewire 3 — server-driven components
  • Flux UI Pro — component library (auth: composer.fluxui.dev)
  • Font Awesome Pro Plus 7.2 — icons (web assets at Claude-Toys/design/)
  • Alpine.js — client-side interactivity (via Livewire)
  • Vite — asset bundling

7.2 Design Reference

  • Host.uk.com uses Stellar theme (Cruip) as base
  • Themes available at Claude-Toys/themes/cruip/
  • mosaic-laravel-livewire for admin dashboard patterns

7.3 Brand

  • UK English (colour, organisation, centre)
  • Professional but approachable
  • Oxford comma, sentence case headings
  • No exclamation marks
  • Banned words: leverage, utilise, seamless, robust, game-changing, best-in-class

8. Inter-Module Communication

8.1 Events

Modules communicate via Laravel events:

// OpenBrain
event(new MemoryStored($memory));
event(new MemoryRecalled($query, $results));

// Agentic
event(new AgentSessionStarted($agentId, $org, $project));
event(new AgentTaskCompleted($agentId, $workspace, $status));

// Commerce
event(new SubscriptionActivated($workspace, $plan));
event(new UsageRecorded($workspace, $metric, $amount));

8.2 Listeners

// Lem listens for memories → update training data
MemoryStored::class => [UpdateTrainingData::class]

// Uptelligence listens for recall latency → track performance
MemoryRecalled::class => [TrackRecallLatency::class]

// Commerce listens for API usage → billing
ApiRequestCompleted::class => [RecordUsage::class]

9. Admin Panel — Forge Section

The admin panel (app.lthn.ai) gets a "Forge" section for managing the software development lifecycle. This surfaces data from Forge (Forgejo), Uptelligence, OpenBrain, and the agent system into one dashboard.

9.1 Forge Overview Dashboard

┌─────────────────────────────────────────────────┐
│ Forge                                            │
├──────────┬──────────┬──────────┬────────────────┤
│ Repos    │ Issues   │ Agents   │ Uptelligence   │
│ 42 total │ 18 open  │ 2 running│ 3 alerts       │
│ 3 dirty  │ 5 urgent │ 8 queued │ 1 degraded     │
└──────────┴──────────┴──────────┴────────────────┘

9.2 Sub-sections

Section Source Shows
Repositories Forge API List repos, branches, last commit, build status, dirty/clean
Issues Forge API Open issues by label (agentic, bug, help-wanted), assignee, priority
Plans Plans API Active plans with phase progress, checkpoints, blockers
Agents Agent Status Running/queued/completed/failed agents, workspace drill-down
Uptelligence Monitoring Service health, response times, alerts needing attention
Migrations Upgrade Guides Pending upgrades, migration plans, dependency graph

9.3 Actionable Items

The dashboard highlights items that need attention:

⚠ Agent dispatch needed:
  - go-build: 3 failing tests since last push (Uptelligence)
  - core-tenant: Issue #45 marked 'agentic' — ready for agent work
  - go-io: Dependency update available (core v0.8.0-alpha.1 → v0.8.0)

🔄 Migrations pending:
  - Laravel 12.x → 13.x: 4 packages affected
  - dappco.re/go/core v0.8.0 → v0.9.0: 20 packages need bumping

Each item has a one-click "Dispatch Agent" action that opens a dispatch dialog with the repo, task, and template pre-filled.

9.4 Livewire Components

App\Livewire\Forge\
├── Dashboard.php           — Overview with counts and alerts
├── RepositoryList.php      — Repo table with status badges
├── IssueBoard.php          — Kanban-style issue board by label
├── PlanProgress.php        — Plan phases with task checkboxes
├── AgentMonitor.php        — Live agent status (polls via wire:poll)
├── UptimeOverview.php      — Service health grid
├── MigrationTracker.php    — Upgrade guides and pending migrations
└── DispatchDialog.php      — Modal for dispatching agents

10. Upgrade Guides — Content Product

Upgrade guides are both an internal tool (keeping the ecosystem current) and a content product (published on lthn.ai/docs for SEO and community value).

10.1 Detection — Uptelligence Software Monitors

Uptelligence monitors software versions from multiple sources. When a new version is detected, it triggers the upgrade guide pipeline.

Monitor Types

Type Source Example
Packagist Packagist API Laravel, Livewire, Pest
GitHub Release GitHub Releases API Go, Node, Qdrant, Ollama
NPM NPM registry API Vite, TailwindCSS
Go Proxy proxy.golang.org Go modules
Custom API Vendor endpoint AltumCode products (66Biolinks, phpAnalytics, etc.)
Web Scrape Configured URL + selector Anything with a version on a page

Monitor Schema

class SoftwareMonitor extends Model
{
    use BelongsToWorkspace;

    protected $fillable = [
        'name',              // "laravel/framework"
        'type',              // "packagist", "github", "npm", "go", "api", "scrape"
        'source',            // URL or package identifier
        'current_version',   // "12.4.1" (last known)
        'latest_version',    // "13.0.0" (last checked)
        'check_interval',    // minutes between checks
        'selector',          // CSS selector for scrape type, JSON path for API
        'headers',           // JSON — custom headers (auth tokens etc.)
        'auto_guide',        // boolean — auto-generate upgrade guide on major bump
        'auto_dispatch',     // boolean — auto-dispatch agents on minor/patch
        'notify_channel',    // "agent.status", "inbox.message", null
        'last_checked_at',
        'last_changed_at',
    ];
}

Check Flow

1. Cron: php artisan uptelligence:check-software (every 15 min)
2. For each monitor:
   a. Fetch latest version from source
   b. Compare with current_version
   c. If changed:
      - Update latest_version + last_changed_at
      - Emit SoftwareUpdateDetected event
      - If major bump + auto_guide: dispatch guide generation
      - If minor/patch + auto_dispatch: dispatch upgrade agents
      - If notify_channel: push notification

AltumCode Integration

// Custom API monitor for AltumCode products
SoftwareMonitor::create([
    'name' => '66Biolinks',
    'type' => 'api',
    'source' => 'https://api.altumcode.com/versions',
    'selector' => '$.biolinks.version',  // JSON path
    'check_interval' => 60,
    'auto_guide' => true,
]);

Events

event(new SoftwareUpdateDetected($monitor, $oldVersion, $newVersion));
event(new UpgradeGuideGenerated($guide));
event(new UpgradeDispatchStarted($guide, $repos));

10.2 Guide Generation

When a library releases a new major version, an agent generates a structured upgrade guide:

  1. Changelog analysis — parse release notes, extract breaking changes
  2. Migration steps — ordered list of code changes needed
  3. Search & replace — specific patterns to find and replace
  4. Test strategy — what to test after upgrading
  5. Rollback plan — how to revert if it breaks

10.3 Guide Schema

class UpgradeGuide extends Model
{
    use BelongsToWorkspace;

    protected $fillable = [
        'library',          // "laravel/framework"
        'from_version',     // "12.0"
        'to_version',       // "13.0"
        'language',         // "php", "go", "js"
        'title',            // "Upgrading Laravel 12 to 13"
        'summary',          // Short description
        'breaking_changes', // JSON array of breaking changes
        'migration_steps',  // JSON array of ordered steps
        'search_replace',   // JSON array of {find, replace, files} patterns
        'test_strategy',    // Markdown
        'rollback_plan',    // Markdown
        'published',        // boolean
        'published_at',     // timestamp
    ];
}

10.4 Generation Flow

1. Detect new release (Uptelligence monitors GitHub/Packagist)
2. Dispatch agent: "Generate upgrade guide for {library} {from}→{to}"
3. Agent reads changelog, analyses breaking changes
4. Agent tests the upgrade on a sample project
5. Agent writes the guide
6. Human reviews in admin panel
7. Publish to lthn.ai/docs/upgrades/{library}/{from}-to-{to}

10.5 Internal Use

The same guides drive internal upgrades:

# List pending upgrades for the ecosystem
php artisan upgrade:check

# Apply an upgrade guide to a specific repo
php artisan upgrade:apply --guide=laravel-12-to-13 --repo=lthn.ai

# Dispatch agents to upgrade all affected repos
php artisan upgrade:dispatch --guide=laravel-12-to-13

10.6 Content Value

Published guides on lthn.ai serve as:

  • SEO content — "how to upgrade Laravel 12 to 13" ranks well
  • Community goodwill — free, practical, maintained
  • Trust signal — shows the platform understands the ecosystem
  • Lead generation — readers discover lthn.ai's other services

10.7 API

GET /v1/upgrades                           — list all guides
GET /v1/upgrades/{library}                 — guides for a library
GET /v1/upgrades/{library}/{from}-to-{to}  — specific guide
POST /v1/upgrades                          — create guide (agent)
PATCH /v1/upgrades/{id}                    — update guide
POST /v1/upgrades/{id}/publish             — publish to site

11. Authentication — Agent OAuth

11.1 Current State

The platform now supports both first-party OAuth client credentials and the legacy static API key path. The fallback API key flow still validates Bearer tokens against agent_api_keys with:

  • Scope-based permissions (brain:read, brain:write, plans:read, etc.)
  • IP whitelisting
  • Rate limiting per key
  • Revocation and expiry

OAuth access tokens are issued from agent_oauth_clients and agent_oauth_access_tokens, then enforced by the shared API credential middleware on protected routes.

11.2 What's Needed: OAuth2 Client Credentials

Agents are service accounts, not users. The OAuth2 Client Credentials flow fits:

Agent (core-agent on homelab) → POST /oauth/token
  { grant_type: "client_credentials", client_id: "charon", client_secret: "..." }
← { access_token: "...", token_type: "Bearer", expires_in: 3600, scope: "brain:read brain:write" }

Agent → GET /v1/brain/recall
  Authorization: Bearer {access_token}

11.3 Implementation

The current repo implements the flow with first-party OAuth client and token models rather than Passport:

// Agent registers as an OAuth client
$client = Passport::client()->create([
    'name' => 'charon',
    'redirect' => '',
    'personal_access_client' => false,
    'password_client' => false,
    'revoked' => false,
]);

// Agent authenticates
POST /oauth/token
{
    "grant_type": "client_credentials",
    "client_id": "{client_id}",
    "client_secret": "{client_secret}",
    "scope": "brain:read brain:write messages:read messages:write"
}

11.4 Agent Identity

Each agent gets an OAuth client that maps to its identity:

Agent Client ID Host Scopes
Cladius cladius M3 Studio (local) brain:* messages:* plans:* sessions:*
Charon charon Homelab (10.69.69.165) brain:* messages:* plans:* dispatch:*
Codex codex Docker containers brain:read plans:read
Clotho clotho Remote brain:read messages:read

11.5 Backward Compatibility

Keep the existing API key auth as a fallback. Both paths work:

// Middleware tries OAuth token first, falls back to API key
public function handle(Request $request, Closure $next, ...$scopes)
{
    // Try OAuth (Passport/Sanctum)
    if ($this->tryOAuth($request, $scopes)) {
        return $next($request);
    }

    // Fall back to API key
    if ($this->tryApiKey($request, $scopes)) {
        return $next($request);
    }

    return $this->unauthorised('Authentication required');
}

11.6 core/agent Integration

core-agent's transport layer (transport.go) needs an OAuth client:

// On startup: exchange credentials for token
func (s *Service) authenticate(ctx context.Context) error {
    r := HTTPPost(ctx, s.apiURL+"/oauth/token", core.JSONMarshalString(map[string]any{
        "grant_type":    "client_credentials",
        "client_id":     s.clientID,
        "client_secret": s.clientSecret,
        "scope":         "brain:read brain:write messages:read messages:write",
    }), "", "")

    // Cache token, refresh before expiry
    s.token = r.Value.(map[string]any)["access_token"].(string)
    s.tokenExpiry = time.Now().Add(time.Duration(expiresIn) * time.Second)
    return nil
}

12. MCP Portal (mcp.lthn.ai)

12.1 Current State

The MCP portal already has Livewire components:

Component Purpose
mcp.dashboard Overview
mcp.api-key-manager Create/revoke API keys
mcp.api-explorer Browse available endpoints
mcp.mcp-metrics Request counts, latency
mcp.mcp-playground Test tool calls interactively
mcp.playground General API playground
mcp.request-log Recent API requests
mcp.unified-search Search across tools/resources

API routes are shared with api.lthn.ai — same endpoints, different domain.

12.2 What's Needed

Feature Status Notes
Tool registry (list/search) Exists Via core-mcp package
API key management Exists Create, revoke, scope
Request playground Exists Interactive tool calls
Metrics dashboard Exists Needs real data pipeline
OAuth client management Implemented Livewire operator surface for issuing and revoking agent clients
Agent status panel Implemented Live view of registrations, capacity, and assigned jobs
Brain explorer Implemented Browse scoped memories, tags, and search results
Webhook configuration Implemented Manage webhook endpoints, secrets, and recent deliveries

12.3 MCP HTTP Bridge

The bridge at /mcp/tools/call proxies HTTP requests to MCP tool calls. This lets web clients and REST consumers use MCP tools without a stdio connection:

POST /mcp/tools/call
Authorization: Bearer {token}
{
    "tool": "brain_recall",
    "arguments": {
        "query": "service registration pattern",
        "org": "core"
    }
}

→ 200 OK
{
    "content": [...],
    "isError": false
}

12.4 Server-Sent Events

For live updates (agent status, brain operations), the MCP portal should support SSE:

GET /mcp/events
Authorization: Bearer {token}
Accept: text/event-stream

data: {"type": "agent.started", "repo": "go-io", "agent": "codex"}
data: {"type": "agent.completed", "repo": "go-io", "status": "completed"}
data: {"type": "brain.indexed", "memory_id": "uuid", "org": "core"}

This connects the web dashboard to the same event stream that Claude Code channels use.


13. Fleet Dispatch — Distributed Agent Network

13.1 Vision

lthn.ai is the fleet controller. core-agent instances run on any machine — homelab, community members' desktops, CI runners — and connect to lthn.ai to receive work. This enables:

  • Distributed compute — work dispatched to wherever there's capacity
  • Community contribution — Lethean community members donate compute by running core-agent
  • Elastic scaling — more agents come online as needed
  • Centralised coordination — lthn.ai decides what runs where

13.2 Architecture

┌──────────────┐
│   lthn.ai    │ ← Fleet controller (PHP)
│  (api + mcp) │
├──────────────┤
│ Job Queue    │ ← Pending dispatch jobs
│ Agent Registry│ ← Which agents are online, their capabilities
│ SSE Stream   │ ← Push jobs to connected agents
└──────┬───────┘
       │
       ├──── core-agent (M3 Studio — Cladius)
       │     └── Claude Max, local repos, full access
       │
       ├──── core-agent (Homelab — Charon)
       │     └── Claude Max, Docker, GPU (RX 7800 XT)
       │
       ├──── core-agent (Community Node)
       │     └── Codex only, sandboxed, limited scopes
       │
       └──── core-agent (CI Runner)
             └── Codex only, ephemeral, build+test only

13.3 Agent Registration

core-agent connects to lthn.ai on startup and registers:

// core-agent startup
POST /v1/agent/register
Authorization: Bearer {oauth_token}
{
    "agent_id": "charon",
    "hostname": "charon.lthn.io",
    "capabilities": ["claude", "codex", "docker", "gpu"],
    "max_concurrent": 3,
    "labels": ["go", "php", "devops"],
    "version": "0.8.0-alpha.1"
}

→ 201 Created
{
    "registration_id": "uuid",
    "sse_url": "/v1/agent/events",
    "heartbeat_interval": 30
}

13.4 Job Queue (PHP Side)

class DispatchJob extends Model
{
    use BelongsToWorkspace;

    protected $fillable = [
        'repo',
        'org',
        'task',
        'agent_type',       // "codex", "claude", "gemini"
        'template',         // "coding", "conventions", "security"
        'branch',
        'priority',         // 1-10
        'labels',           // JSON — match against agent labels
        'status',           // "pending", "assigned", "running", "completed", "failed"
        'assigned_agent',   // agent_id that picked it up
        'assigned_at',
        'completed_at',
        'result',           // JSON — output from agent
    ];
}

13.5 Job Assignment Flow

1. User/system creates DispatchJob (via admin panel, API, or Uptelligence trigger)
2. lthn.ai checks registered agents for matching capabilities + labels
3. For connected agents (SSE): push job immediately
4. For polling agents: return job on next checkin
5. Agent accepts job → status = "assigned"
6. Agent preps workspace, spawns subagent → status = "running"
7. Agent reports completion → status = "completed" with result
8. lthn.ai fires events (AgentCompleted → channel notification, queue next)

13.6 SSE Event Stream

Connected agents receive jobs in real-time:

GET /v1/agent/events
Authorization: Bearer {oauth_token}

event: job.assigned
data: {"job_id": "uuid", "repo": "go-io", "task": "AX polish", "agent_type": "codex"}

event: job.cancelled
data: {"job_id": "uuid", "reason": "superseded"}

event: ping
data: {"timestamp": "2026-03-27T15:00:00Z"}

13.7 Polling Fallback

Agents behind NAT or firewalls poll instead of SSE:

GET /v1/agent/checkin?agent_id=charon
Authorization: Bearer {oauth_token}

→ 200 OK
{
    "jobs": [
        {"job_id": "uuid", "repo": "go-io", "task": "AX polish", "agent_type": "codex"}
    ],
    "messages": [
        {"id": 170, "from": "cladius", "subject": "next batch", "content": "..."}
    ]
}

13.8 core-agent Integration (Go Side)

core-agent gets a fleet mode that connects to lthn.ai:

// core-agent fleet — connect to lthn.ai fleet controller
c.Command("fleet", core.Command{
    Description: "Connect to lthn.ai fleet controller and accept dispatched work",
    Action: func(opts core.Options) core.Result {
        fleet := NewFleetClient(c, FleetOptions{
            APIUrl:   "https://api.lthn.ai",
            AgentID:  core.Env("AGENT_ID"),
            ClientID: core.Env("OAUTH_CLIENT_ID"),
            Secret:   core.Env("OAUTH_CLIENT_SECRET"),
        })
        return fleet.Run(ctx) // SSE connect + heartbeat + job execution loop
    },
})

13.9 Systray App

For community members, core-agent runs as a systray application:

┌──────────────────────┐
│ 🟢 Lethean Agent     │
│ Connected to lthn.ai │
│ Jobs: 2 running      │
│ ─────────────────── │
│ Settings...          │
│ View logs...         │
│ Pause                │
│ Quit                 │
└──────────────────────┘

Built with core/go-webview (Wails WebView2). The agent runs in the background, connects to lthn.ai, accepts jobs within configured limits (max concurrent, allowed agent types, repo restrictions).

13.10 Community Onboarding

1. Download core-agent from lthn.ai/download
2. Run installer → creates systray app
3. Sign in with lthn.ai account → OAuth token
4. Configure: max concurrent jobs, GPU availability, allowed repos
5. Agent connects to fleet → starts receiving work

13.11 Security for Community Nodes

  • All work runs in Docker containers (sandboxed)
  • Community nodes only get Codex jobs (no Claude — no API key sharing)
  • No access to private repos unless explicitly whitelisted
  • Results are verified before merging (CodeRabbit + human review)
  • API scopes limited: dispatch:execute only, no brain:write

14. PHP Agent Package (core/agent/php)

14.1 Current State

The PHP agent package at core/agent/php provides the server-side of the agent system:

Component Files Purpose
Controllers 10 API controllers REST endpoints for plans, sessions, issues, brain, messages
Services 12 service classes BrainService, AgenticManager, ForgejoService, Claude/Gemini/OpenAI
Models 14 Eloquent models Plans, sessions, memories, messages, API keys, sprints, tasks
Jobs Queue jobs Async processing
Middleware AgentApiAuth Bearer token + scope validation
Routes api.php (109 lines) Full REST API for agent operations
Migrations DB schemas brain_memories, agent_plans, agent_sessions, etc.

14.2 What's Needed

Feature Status Notes
BrainService async embedding Implemented EmbedMemory queue job with indexed_at tracking
BrainService org scoping Implemented Scope columns, filters, and Qdrant payload support
Elasticsearch integration Implemented Search, tags, and scopes discovery endpoints
DispatchJob model Implemented Fleet job queue with API and Forge composer wiring
AgentRegistration model Implemented Fleet agent registry with heartbeat tracking
SSE controller Implemented Real-time fleet and MCP event streams
Fleet checkin endpoint Implemented Polling fallback assigns matching work during check-in
OAuth client management Implemented First-party client credentials issuer and token store
Software monitor model Implemented Uptelligence release tracking and guide triggers
Upgrade guide model Implemented Draft, publish, and retrieval flow for upgrade content
Test coverage Expanded RFC and supporting surfaces are covered by the passing local suite

14.3 Integration with lthn.ai

The PHP package is installed in lthn.ai via Composer:

{
    "repositories": [
        {
            "type": "path",
            "url": "../core/agent/php"
        }
    ],
    "require": {
        "lthn/agent": "@dev"
    }
}

All models, migrations, routes, and services register via the Boot.php service provider. lthn.ai adds its own Website modules (Api, Mcp, App) that consume the package's services.


15. Observability

15.1 Self-Monitoring

lthn.ai monitors itself via the Uptelligence module. Key metrics:

Metric Source Alert Threshold
API response time Middleware timing p95 > 500ms
Error rate Exception handler > 1% of requests
Queue depth Laravel Horizon/Redis > 100 pending jobs
Agent fleet size Agent registry < 1 connected agent
Brain embed queue EmbedMemory job count > 50 pending
Qdrant health /collections endpoint non-200
Ollama health /api/tags endpoint non-200
Elasticsearch health /_cluster/health status != green
Disk usage Host metrics > 85%
MariaDB connections SHOW STATUS > 80% of max

15.2 Metrics Storage

class Metric extends Model
{
    protected $fillable = [
        'name',        // "api.response_time.p95"
        'value',       // 245.5
        'unit',        // "ms", "count", "percent", "bytes"
        'tags',        // JSON {"endpoint": "/v1/brain/recall", "method": "POST"}
        'recorded_at',
    ];
}

15.3 Dashboard

Uptelligence section in admin panel shows:

  • Real-time service health grid (green/amber/red)
  • API latency graph (last 24h)
  • Queue depth over time
  • Agent fleet status (online/offline/busy)
  • Error log (last 50 errors with stack traces)

15.4 Alerting

// Uptelligence checks run on schedule
$schedule->command('uptelligence:check')->everyMinute();

// Alerts dispatch via:
event(new AlertTriggered($metric, $threshold, $value));

// Listeners:
AlertTriggered::class => [
    SendChannelNotification::class,   // Push to agent channel
    SendSlackNotification::class,     // If configured
    CreateIssue::class,               // Auto-create Forge issue
    DispatchAgent::class,             // Auto-dispatch fix agent if auto_dispatch enabled
]

16. Webhook Ingress

16.1 Sources

Source Endpoint Trigger
Forge (Forgejo) POST /webhooks/forge Push, PR, issue, release
GitHub POST /github/webhook Push, PR (mirror repos)
CI Runner POST /webhooks/ci Build pass/fail
Uptelligence Internal event Software update detected
Deploy POST /webhooks/deploy Deploy success/failure

16.2 Webhook Processing

class WebhookController extends Controller
{
    public function forge(Request $request): JsonResponse
    {
        $event = $request->header('X-Forgejo-Event');
        $payload = $request->all();

        match ($event) {
            'push' => event(new ForgePushReceived($payload)),
            'pull_request' => event(new ForgePRReceived($payload)),
            'issues' => event(new ForgeIssueReceived($payload)),
            'release' => event(new ForgeReleaseReceived($payload)),
            default => null,
        };

        return response()->json(['ok' => true]);
    }
}

16.3 Event → Action Mapping

Event Action
Push to dev Run QA on changed packages
PR created Dispatch CodeRabbit review
Issue labelled 'agentic' Dispatch agent to work on it
Release published Trigger upgrade guide check for consumers
CI build failed Create Forge issue + dispatch fix agent
Deploy success Run smoke tests via Uptelligence
Software update detected Generate upgrade guide

17. Documentation Site (docs.lthn.ai)

17.1 Architecture

docs.lthn.ai serves documentation from two sources:

  • Static docs — MkDocs Material (core.help content), deployed as static files
  • Dynamic content — Upgrade guides generated by agents, served from database
  • API docs — OpenAPI spec auto-generated, served via Scalar/Swagger

17.2 Content Structure

docs.lthn.ai/
├── getting-started/     ← Static (MkDocs)
├── go/                  ← Static (Core Go docs)
├── php/                 ← Static (CorePHP docs)
├── api/                 ← Dynamic (OpenAPI spec)
├── upgrades/            ← Dynamic (generated upgrade guides)
│   ├── laravel/
│   │   └── 12-to-13/
│   ├── go/
│   │   └── 1.25-to-1.26/
│   └── tailwindcss/
│       └── 3-to-4/
└── reference/           ← Static (RFC specs)

17.3 Search

Docs search powered by the same Elasticsearch instance as OpenBrain:

GET /v1/docs/search?q=service+registration

→ { "hits": [...], "categories": ["go", "php", "api"] }

18. LEM Module

18.1 Purpose

LEM (Lethean Ethical Model) provides AI ethical scoring and model management.

18.2 Current State

Component Status
ScoreEthics action Exists
ScoreImprint action Exists
LemController API Exists
ScoringActionsTest Exists (1 test file)
EaaS scoring endpoints Exists (/v1/score/*)

18.3 Scoring Types

Endpoint Purpose
/v1/score/content Score text content for ethical concerns
/v1/score/imprint Score AI model's training data imprint
/v1/score/model Score a model's overall ethical profile
/v1/score/full Combined comprehensive score
/v1/score/session/* Multi-turn scoring session

18.4 What's Needed

  • Test coverage for all scoring actions
  • Integration with OpenBrain (store scoring decisions as memories)
  • Scoring dashboard in admin panel
  • API documentation for EaaS consumers

19. Studio Module

19.1 Purpose

Multimedia pipeline — image generation, voice synthesis, remix/mashup.

19.2 Current State

Controller Endpoints Status
ImageController Image generation API Exists
VoiceController Voice synthesis API Exists
AssetController Asset management Exists
RemixController Remix/mashup pipeline Exists

19.3 Scope

Studio is functional but not in scope for initial production launch. It ships when it ships. Focus is on brain, fleet, and API stability first.


20. Backup and Recovery

20.1 Strategy

Component Method Frequency Retention Location
MariaDB mariadb-dump + Galera snapshots Hourly 7 days Garage S3
Qdrant Collection snapshots via API Daily 30 days Garage S3
Elasticsearch Snapshot API Daily 14 days Garage S3
Redis/Dragonfly RDB snapshots Hourly 3 days Local
Uploads S3 sync Real-time Indefinite Garage S3
Config/Env Git (DevOps repo) On change Indefinite Forge

20.2 Restore Procedure

# MariaDB — restore from S3
ansible-playbook playbooks/restore_mariadb.yml -e "snapshot=2026-03-27-14"

# Qdrant — restore collection
curl -X POST "http://qdrant:6334/collections/openbrain/snapshots/recover" \
  -d '{"location": "s3://backups/qdrant/openbrain-2026-03-27.snapshot"}'

# Elasticsearch — restore from snapshot
curl -X POST "http://elasticsearch:9200/_snapshot/s3_backup/snap_2026-03-27/_restore"

# Full rebuild from MariaDB (nuclear option)
php artisan brain:reindex          # Rebuild Qdrant + ES from MariaDB
php artisan uptelligence:rebuild   # Rebuild monitoring from config

20.3 Automated Backup

# Cron on de1 (via Ansible)
0 * * * * /opt/scripts/backup-mariadb.sh
0 3 * * * /opt/scripts/backup-qdrant.sh
0 4 * * * /opt/scripts/backup-elasticsearch.sh

21. Production Checklist

Before lthn.ai goes live:

  • Brain async embedding (queue job)
  • Brain org scoping (migration + backfill)
  • Elasticsearch setup + indexing
  • API test coverage (every endpoint)
  • Workspace hierarchy (parent_id migration)
  • Admin panel project overview
  • Admin panel Forge section (repos, issues, agents, monitoring)
  • Upgrade guide model + API
  • Upgrade guide generation flow (agent dispatch)
  • Deploy pipeline tested (Ansible → de1)
  • SSL certs (Traefik + Let's Encrypt)
  • Monitoring (Uptelligence self-monitoring)
  • OAuth client credentials
  • Agent OAuth clients provisioned (Cladius, Charon)
  • core/agent OAuth integration (token exchange + refresh)
  • MCP portal — OAuth client management UI
  • MCP portal — agent status panel
  • MCP portal — brain explorer
  • MCP portal — SSE event stream
  • Uptelligence software monitors
  • Rate limiting verified
  • Observability (self-monitoring metrics + alerts)
  • Webhook ingress (Forge, GitHub, CI, deploy)
  • docs.lthn.ai (static + dynamic + API docs)
  • LEM scoring test coverage
  • Backup automation (MariaDB, Qdrant, ES → S3)
  • Restore procedure tested

Changelog

  • 2026-03-27: Initial draft — platform overview, architecture, OpenBrain, workspaces, API, testing
  • 2026-03-27: Added Forge admin section, upgrade guides content product
  • 2026-03-27: Added OAuth agent auth, MCP portal spec, Uptelligence software monitors
  • 2026-03-27: Added fleet dispatch (distributed agent network), PHP agent package spec, community onboarding
  • 2026-03-27: Added observability, webhook ingress, docs site, LEM, Studio, backup/recovery
  • 2026-03-31: Synced the mirrored RFC to the verified implementation baseline in this repo
  • 2026-03-31: Expanded API coverage across MCP bridge, score proxy, docs, messages, plans, sessions, and health routes