762 lines
32 KiB
HTML
762 lines
32 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>Doc Lifecycle - VAPORA Platform Documentation</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta name="description" content="Comprehensive documentation for VAPORA, an intelligent development orchestration platform built entirely in Rust.">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
<link rel="icon" href="../favicon.svg">
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|
<link rel="stylesheet" href="../css/general.css">
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
|
|
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
|
|
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
|
|
|
|
<!-- Provide site root and default themes to javascript -->
|
|
<script>
|
|
const path_to_root = "../";
|
|
const default_light_theme = "light";
|
|
const default_dark_theme = "dark";
|
|
</script>
|
|
<!-- Start loading toc.js asap -->
|
|
<script src="../toc.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="mdbook-help-container">
|
|
<div id="mdbook-help-popup">
|
|
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
|
|
<div>
|
|
<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
|
|
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
|
|
<p>Press <kbd>?</kbd> to show this help</p>
|
|
<p>Press <kbd>Esc</kbd> to hide this help</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="body-container">
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script>
|
|
try {
|
|
let theme = localStorage.getItem('mdbook-theme');
|
|
let sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script>
|
|
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
|
|
let theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
const html = document.documentElement;
|
|
html.classList.remove('light')
|
|
html.classList.add(theme);
|
|
html.classList.add("js");
|
|
</script>
|
|
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script>
|
|
let sidebar = null;
|
|
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
} else {
|
|
sidebar = 'hidden';
|
|
}
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
|
html.classList.remove('sidebar-visible');
|
|
html.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<!-- populated by js -->
|
|
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
|
<noscript>
|
|
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
|
</noscript>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
|
<div class="sidebar-resize-indicator"></div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky">
|
|
<div class="left-buttons">
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</label>
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
</ul>
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">VAPORA Platform Documentation</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
<a href="https://github.com/vapora-platform/vapora" title="Git repository" aria-label="Git repository">
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
|
</a>
|
|
<a href="https://github.com/vapora-platform/vapora/edit/main/docs/src/../integrations/doc-lifecycle.md" title="Suggest an edit" aria-label="Suggest an edit">
|
|
<i id="git-edit-button" class="fa fa-edit"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script>
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<h1 id="doc-lifecycle-manager-integration-guide"><a class="header" href="#doc-lifecycle-manager-integration-guide">Doc-Lifecycle-Manager Integration Guide</a></h1>
|
|
<h2 id="overview"><a class="header" href="#overview">Overview</a></h2>
|
|
<p><strong>doc-lifecycle-manager</strong> (external project) provides complete documentation lifecycle management for VAPORA, including classification, consolidation, semantic search, real-time updates, and enterprise security features.</p>
|
|
<p><strong>Project Location</strong>: External project (doc-lifecycle-manager)
|
|
<strong>Status</strong>: ✅ <strong>Enterprise-Ready</strong>
|
|
<strong>Tests</strong>: 155/155 passing | Zero unsafe code</p>
|
|
<hr />
|
|
<h2 id="what-is-doc-lifecycle-manager"><a class="header" href="#what-is-doc-lifecycle-manager">What is doc-lifecycle-manager?</a></h2>
|
|
<p>A comprehensive Rust-based system that handles documentation throughout its entire lifecycle:</p>
|
|
<h3 id="core-capabilities-phases-1-3"><a class="header" href="#core-capabilities-phases-1-3">Core Capabilities (Phases 1-3)</a></h3>
|
|
<ul>
|
|
<li><strong>Automatic Classification</strong>: Categorizes docs (vision, design, specs, ADRs, guides, testing, archive)</li>
|
|
<li><strong>Duplicate Detection</strong>: Finds similar documents with TF-IDF analysis</li>
|
|
<li><strong>Semantic RAG Indexing</strong>: Vector embeddings for semantic search</li>
|
|
<li><strong>mdBook Generation</strong>: Auto-generates documentation websites</li>
|
|
</ul>
|
|
<h3 id="enterprise-features-phases-4-7"><a class="header" href="#enterprise-features-phases-4-7">Enterprise Features (Phases 4-7)</a></h3>
|
|
<ul>
|
|
<li><strong>GraphQL API</strong>: Semantic document queries with pagination</li>
|
|
<li><strong>Real-Time Events</strong>: WebSocket streaming of doc updates</li>
|
|
<li><strong>Distributed Tracing</strong>: OpenTelemetry with W3C Trace Context</li>
|
|
<li><strong>Security</strong>: mTLS with automatic certificate rotation</li>
|
|
<li><strong>Performance</strong>: Comprehensive benchmarking with percentiles</li>
|
|
<li><strong>Persistence</strong>: SurrealDB backend (feature-gated)</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="integration-architecture"><a class="header" href="#integration-architecture">Integration Architecture</a></h2>
|
|
<h3 id="data-flow-in-vapora"><a class="header" href="#data-flow-in-vapora">Data Flow in VAPORA</a></h3>
|
|
<pre><code>Frontend/Agents
|
|
↓
|
|
┌─────────────────────────────────┐
|
|
│ VAPORA API Layer (Axum) │
|
|
│ ├─ REST endpoints │
|
|
│ └─ WebSocket gateway │
|
|
└─────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────┐
|
|
│ doc-lifecycle-manager Services │
|
|
│ │
|
|
│ ├─ GraphQL Resolver │
|
|
│ ├─ WebSocket Manager │
|
|
│ ├─ Document Classifier │
|
|
│ ├─ RAG Indexer │
|
|
│ └─ mTLS Auth Manager │
|
|
└─────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────┐
|
|
│ Data Layer │
|
|
│ ├─ SurrealDB (vectors) │
|
|
│ ├─ NATS JetStream (events) │
|
|
│ └─ Redis (cache) │
|
|
└─────────────────────────────────┘
|
|
</code></pre>
|
|
<h3 id="component-integration-points"><a class="header" href="#component-integration-points">Component Integration Points</a></h3>
|
|
<p><strong>1. Documenter Agent ↔ doc-lifecycle-manager</strong></p>
|
|
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
|
</span><span class="boring">fn main() {
|
|
</span>use vapora_doc_lifecycle::prelude::*;
|
|
|
|
// On task completion
|
|
async fn on_task_completed(task_id: &str) {
|
|
let config = PluginConfig::default();
|
|
let mut docs = DocumenterIntegration::new(config)?;
|
|
docs.on_task_completed(task_id).await?;
|
|
}
|
|
<span class="boring">}</span></code></pre></pre>
|
|
<p><strong>2. Frontend ↔ GraphQL API</strong></p>
|
|
<pre><code class="language-graphql">{
|
|
documentSearch(query: {
|
|
text_query: "authentication"
|
|
limit: 10
|
|
}) {
|
|
results { id title relevance_score }
|
|
}
|
|
}
|
|
</code></pre>
|
|
<p><strong>3. Frontend ↔ WebSocket Events</strong></p>
|
|
<pre><code class="language-javascript">const ws = new WebSocket("ws://vapora/doc-events");
|
|
ws.onmessage = (event) => {
|
|
const { event_type, payload } = JSON.parse(event.data);
|
|
// Update UI on document_indexed, document_updated, etc.
|
|
};
|
|
</code></pre>
|
|
<p><strong>4. Agent-to-Agent ↔ NATS JetStream</strong></p>
|
|
<pre><code>Task Completed Event
|
|
→ Documenter Agent (NATS)
|
|
→ Classify + Index
|
|
→ Broadcast DocumentIndexed Event
|
|
→ All Agents notified
|
|
</code></pre>
|
|
<hr />
|
|
<h2 id="feature-set-by-phase"><a class="header" href="#feature-set-by-phase">Feature Set by Phase</a></h2>
|
|
<h3 id="phase-1-foundation--core-library-"><a class="header" href="#phase-1-foundation--core-library-">Phase 1: Foundation & Core Library ✅</a></h3>
|
|
<ul>
|
|
<li>Error handling and configuration</li>
|
|
<li>Core abstractions and types</li>
|
|
</ul>
|
|
<h3 id="phase-2-extended-implementation-"><a class="header" href="#phase-2-extended-implementation-">Phase 2: Extended Implementation ✅</a></h3>
|
|
<ul>
|
|
<li>Document Classifier (7 types)</li>
|
|
<li>Consolidator (TF-IDF)</li>
|
|
<li>RAG Indexer (markdown-aware)</li>
|
|
<li>MDBook Generator</li>
|
|
</ul>
|
|
<h3 id="phase-3-cli--automation-"><a class="header" href="#phase-3-cli--automation-">Phase 3: CLI & Automation ✅</a></h3>
|
|
<ul>
|
|
<li>4 command handlers</li>
|
|
<li>62+ Just recipes</li>
|
|
<li>5 NuShell scripts</li>
|
|
</ul>
|
|
<h3 id="phase-4-vapora-deep-integration-"><a class="header" href="#phase-4-vapora-deep-integration-">Phase 4: VAPORA Deep Integration ✅</a></h3>
|
|
<ul>
|
|
<li>NATS JetStream events</li>
|
|
<li>Vector store trait</li>
|
|
<li>Plugin system</li>
|
|
<li>Agent coordination</li>
|
|
</ul>
|
|
<h3 id="phase-5-production-hardening-"><a class="header" href="#phase-5-production-hardening-">Phase 5: Production Hardening ✅</a></h3>
|
|
<ul>
|
|
<li>Real NATS integration</li>
|
|
<li>DocServer RBAC (4 roles, 3 visibility levels)</li>
|
|
<li>Root Files Keeper (auto-update README, CHANGELOG)</li>
|
|
<li>Kubernetes manifests (7 YAML files)</li>
|
|
</ul>
|
|
<h3 id="phase-6-multi-agent-vapora-"><a class="header" href="#phase-6-multi-agent-vapora-">Phase 6: Multi-Agent VAPORA ✅</a></h3>
|
|
<ul>
|
|
<li>Agent registry with health checking</li>
|
|
<li>CI/CD pipeline (GitHub Actions)</li>
|
|
<li>Prometheus monitoring rules</li>
|
|
<li>Comprehensive documentation</li>
|
|
</ul>
|
|
<h3 id="phase-7-advanced-features-"><a class="header" href="#phase-7-advanced-features-">Phase 7: Advanced Features ✅</a></h3>
|
|
<ul>
|
|
<li><strong>SurrealDB Backend</strong>: Persistent vector store</li>
|
|
<li><strong>OpenTelemetry</strong>: W3C Trace Context support</li>
|
|
<li><strong>GraphQL API</strong>: Query builder with semantic search</li>
|
|
<li><strong>WebSocket Events</strong>: Real-time subscriptions</li>
|
|
<li><strong>mTLS Auth</strong>: Certificate rotation</li>
|
|
<li><strong>Benchmarking</strong>: P95/P99 metrics</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="how-to-use-in-vapora"><a class="header" href="#how-to-use-in-vapora">How to Use in VAPORA</a></h2>
|
|
<h3 id="1-basic-integration-documenter-agent"><a class="header" href="#1-basic-integration-documenter-agent">1. Basic Integration (Documenter Agent)</a></h3>
|
|
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
|
</span><span class="boring">fn main() {
|
|
</span>// In vapora-backend/documenter_agent.rs
|
|
|
|
use vapora_doc_lifecycle::prelude::*;
|
|
|
|
impl DocumenterAgent {
|
|
async fn process_task(&self, task: Task) -> Result<()> {
|
|
let config = PluginConfig::default();
|
|
let mut integration = DocumenterIntegration::new(config)?;
|
|
|
|
// Automatically classifies, indexes, and generates docs
|
|
integration.on_task_completed(&task.id).await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
<span class="boring">}</span></code></pre></pre>
|
|
<h3 id="2-graphql-queries-frontendagents"><a class="header" href="#2-graphql-queries-frontendagents">2. GraphQL Queries (Frontend/Agents)</a></h3>
|
|
<pre><code class="language-graphql"># Search for documentation
|
|
query SearchDocs($query: String!) {
|
|
documentSearch(query: {
|
|
text_query: $query
|
|
limit: 10
|
|
visibility: "Public"
|
|
}) {
|
|
results {
|
|
id
|
|
title
|
|
path
|
|
relevance_score
|
|
preview
|
|
}
|
|
total_count
|
|
has_more
|
|
}
|
|
}
|
|
|
|
# Get specific document
|
|
query GetDoc($id: ID!) {
|
|
document(id: $id) {
|
|
id
|
|
title
|
|
content
|
|
metadata {
|
|
created_at
|
|
updated_at
|
|
owner_id
|
|
}
|
|
}
|
|
}
|
|
</code></pre>
|
|
<h3 id="3-real-time-updates-frontend"><a class="header" href="#3-real-time-updates-frontend">3. Real-Time Updates (Frontend)</a></h3>
|
|
<pre><code class="language-javascript">// Connect to doc-lifecycle WebSocket
|
|
const docWs = new WebSocket('ws://vapora-api/doc-lifecycle/events');
|
|
|
|
// Subscribe to document changes
|
|
docWs.onopen = () => {
|
|
docWs.send(JSON.stringify({
|
|
type: 'subscribe',
|
|
event_types: ['document_indexed', 'document_updated', 'search_index_rebuilt'],
|
|
min_priority: 5
|
|
}));
|
|
};
|
|
|
|
// Handle updates
|
|
docWs.onmessage = (event) => {
|
|
const message = JSON.parse(event.data);
|
|
|
|
if (message.event_type === 'document_indexed') {
|
|
console.log('New doc indexed:', message.payload);
|
|
// Refresh documentation view
|
|
}
|
|
};
|
|
</code></pre>
|
|
<h3 id="4-distributed-tracing"><a class="header" href="#4-distributed-tracing">4. Distributed Tracing</a></h3>
|
|
<p>All operations are automatically traced:</p>
|
|
<pre><code>GET /api/documents?search=auth
|
|
trace_id: 0af7651916cd43dd8448eb211c80319c
|
|
span_id: b7ad6b7169203331
|
|
|
|
├─ graphql_resolver [15ms]
|
|
│ ├─ rbac_check [2ms]
|
|
│ └─ semantic_search [12ms]
|
|
└─ response [1ms]
|
|
</code></pre>
|
|
<h3 id="5-mtls-security"><a class="header" href="#5-mtls-security">5. mTLS Security</a></h3>
|
|
<p>Service-to-service communication is secured:</p>
|
|
<pre><code class="language-yaml"># Kubernetes secret for certs
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: doc-lifecycle-certs
|
|
data:
|
|
server.crt: <base64>
|
|
server.key: <base64>
|
|
ca.crt: <base64>
|
|
</code></pre>
|
|
<hr />
|
|
<h2 id="deployment-in-vapora"><a class="header" href="#deployment-in-vapora">Deployment in VAPORA</a></h2>
|
|
<h3 id="kubernetes-manifests-provided"><a class="header" href="#kubernetes-manifests-provided">Kubernetes Manifests Provided</a></h3>
|
|
<pre><code>kubernetes/
|
|
├── namespace.yaml # Create doc-lifecycle namespace
|
|
├── configmap.yaml # Configuration
|
|
├── deployment.yaml # Main service (2 replicas)
|
|
├── statefulset-nats.yaml # NATS JetStream (3 replicas)
|
|
├── statefulset-surreal.yaml # SurrealDB (1 replica)
|
|
├── service.yaml # Internal services
|
|
├── rbac.yaml # RBAC configuration
|
|
└── prometheus-rules.yaml # Monitoring rules
|
|
</code></pre>
|
|
<h3 id="quick-deploy"><a class="header" href="#quick-deploy">Quick Deploy</a></h3>
|
|
<pre><code class="language-bash"># Deploy to VAPORA cluster
|
|
kubectl apply -f /Tools/doc-lifecycle-manager/kubernetes/
|
|
|
|
# Verify
|
|
kubectl get pods -n doc-lifecycle
|
|
kubectl get svc -n doc-lifecycle
|
|
</code></pre>
|
|
<h3 id="configuration-via-configmap"><a class="header" href="#configuration-via-configmap">Configuration via ConfigMap</a></h3>
|
|
<pre><code class="language-yaml">apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: doc-lifecycle-config
|
|
namespace: doc-lifecycle
|
|
data:
|
|
config.json: |
|
|
{
|
|
"mode": "full",
|
|
"classification": {
|
|
"auto_classify": true,
|
|
"confidence_threshold": 0.8
|
|
},
|
|
"rag": {
|
|
"enable_embeddings": true,
|
|
"max_chunk_size": 512
|
|
},
|
|
"nats": {
|
|
"server": "nats://nats:4222",
|
|
"jetstream_enabled": true
|
|
},
|
|
"otel": {
|
|
"enabled": true,
|
|
"jaeger_endpoint": "http://jaeger:14268"
|
|
},
|
|
"mtls": {
|
|
"enabled": true,
|
|
"rotation_days": 30
|
|
}
|
|
}
|
|
</code></pre>
|
|
<hr />
|
|
<h2 id="vapora-agent-integration"><a class="header" href="#vapora-agent-integration">VAPORA Agent Integration</a></h2>
|
|
<h3 id="documenter-agent"><a class="header" href="#documenter-agent">Documenter Agent</a></h3>
|
|
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
|
</span><span class="boring">fn main() {
|
|
</span>// Processes documentation tasks
|
|
pub struct DocumenterAgent {
|
|
integration: DocumenterIntegration,
|
|
nats: NatsEventHandler,
|
|
}
|
|
|
|
impl DocumenterAgent {
|
|
pub async fn handle_task(&self, task: Task) -> Result<()> {
|
|
// 1. Classify document
|
|
self.integration.on_task_completed(&task.id).await?;
|
|
|
|
// 2. Broadcast via NATS
|
|
let event = DocsUpdatedEvent {
|
|
task_id: task.id,
|
|
doc_count: 5,
|
|
};
|
|
self.nats.publish_docs_updated(event).await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
<span class="boring">}</span></code></pre></pre>
|
|
<h3 id="developer-agent-uses-search"><a class="header" href="#developer-agent-uses-search">Developer Agent (Uses Search)</a></h3>
|
|
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
|
</span><span class="boring">fn main() {
|
|
</span>// Searches for relevant documentation
|
|
pub struct DeveloperAgent;
|
|
|
|
impl DeveloperAgent {
|
|
pub async fn find_relevant_docs(&self, task: Task) -> Result<Vec<DocumentResult>> {
|
|
// GraphQL query for semantic search
|
|
let query = DocumentQuery {
|
|
text_query: Some(task.description),
|
|
limit: Some(5),
|
|
visibility: Some("Internal".to_string()),
|
|
..Default::default()
|
|
};
|
|
|
|
// Execute search
|
|
resolver.resolve_document_search(query, user).await
|
|
}
|
|
}
|
|
<span class="boring">}</span></code></pre></pre>
|
|
<h3 id="codereviewer-agent-uses-context"><a class="header" href="#codereviewer-agent-uses-context">CodeReviewer Agent (Uses Context)</a></h3>
|
|
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
|
</span><span class="boring">fn main() {
|
|
</span>// Uses documentation as context for reviews
|
|
pub struct CodeReviewerAgent;
|
|
|
|
impl CodeReviewerAgent {
|
|
pub async fn review_with_context(&self, code: &str) -> Result<Review> {
|
|
// Search for related documentation
|
|
let docs = semantic_search(code_summary).await?;
|
|
|
|
// Use docs as context in review
|
|
let review = llm_client
|
|
.review_code(code, &docs.to_context_string())
|
|
.await?;
|
|
|
|
Ok(review)
|
|
}
|
|
}
|
|
<span class="boring">}</span></code></pre></pre>
|
|
<hr />
|
|
<h2 id="performance--scaling"><a class="header" href="#performance--scaling">Performance & Scaling</a></h2>
|
|
<h3 id="expected-performance"><a class="header" href="#expected-performance">Expected Performance</a></h3>
|
|
<div class="table-wrapper"><table><thead><tr><th>Operation</th><th>Latency</th><th>Throughput</th></tr></thead><tbody>
|
|
<tr><td>Classify doc</td><td><10ms</td><td>1000 docs/sec</td></tr>
|
|
<tr><td>GraphQL query</td><td><200ms</td><td>50 queries/sec</td></tr>
|
|
<tr><td>WebSocket broadcast</td><td><20ms</td><td>1000 events/sec</td></tr>
|
|
<tr><td>Semantic search</td><td><100ms</td><td>50 searches/sec</td></tr>
|
|
<tr><td>mTLS validation</td><td><5ms</td><td>N/A</td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
<h3 id="resource-requirements"><a class="header" href="#resource-requirements">Resource Requirements</a></h3>
|
|
<p><strong>Deployment Resources</strong>:</p>
|
|
<ul>
|
|
<li>CPU: 2-4 cores (main service)</li>
|
|
<li>Memory: 512MB-2GB</li>
|
|
<li>Storage: 50GB (SurrealDB + vectors)</li>
|
|
</ul>
|
|
<p><strong>NATS Requirements</strong>:</p>
|
|
<ul>
|
|
<li>CPU: 1-2 cores</li>
|
|
<li>Memory: 256MB-1GB</li>
|
|
<li>Persistent volume: 20GB</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="monitoring--observability"><a class="header" href="#monitoring--observability">Monitoring & Observability</a></h2>
|
|
<h3 id="prometheus-metrics"><a class="header" href="#prometheus-metrics">Prometheus Metrics</a></h3>
|
|
<pre><code class="language-promql"># Error rate
|
|
rate(doc_lifecycle_errors_total[5m])
|
|
|
|
# Latency
|
|
histogram_quantile(0.99, doc_lifecycle_request_duration_seconds)
|
|
|
|
# Service availability
|
|
up{job="doc-lifecycle"}
|
|
</code></pre>
|
|
<h3 id="distributed-tracing"><a class="header" href="#distributed-tracing">Distributed Tracing</a></h3>
|
|
<p>Traces are sent to Jaeger in W3C format:</p>
|
|
<pre><code>Trace: 0af7651916cd43dd8448eb211c80319c
|
|
├─ Span: graphql_resolver
|
|
│ ├─ Span: rbac_check
|
|
│ └─ Span: semantic_search
|
|
└─ Span: response
|
|
</code></pre>
|
|
<h3 id="health-checks"><a class="header" href="#health-checks">Health Checks</a></h3>
|
|
<pre><code class="language-bash"># Liveness probe
|
|
curl http://doc-lifecycle:8080/health/live
|
|
|
|
# Readiness probe
|
|
curl http://doc-lifecycle:8080/health/ready
|
|
</code></pre>
|
|
<hr />
|
|
<h2 id="configuration-reference"><a class="header" href="#configuration-reference">Configuration Reference</a></h2>
|
|
<h3 id="environment-variables"><a class="header" href="#environment-variables">Environment Variables</a></h3>
|
|
<pre><code class="language-bash"># Core
|
|
DOC_LIFECYCLE_MODE=full # minimal|standard|full
|
|
DOC_LIFECYCLE_ENABLED=true
|
|
|
|
# Classification
|
|
CLASSIFIER_AUTO_CLASSIFY=true
|
|
CLASSIFIER_CONFIDENCE_THRESHOLD=0.8
|
|
|
|
# RAG/Search
|
|
RAG_ENABLE_EMBEDDINGS=true
|
|
RAG_MAX_CHUNK_SIZE=512
|
|
RAG_CHUNK_OVERLAP=50
|
|
|
|
# NATS
|
|
NATS_SERVER_URL=nats://nats:4222
|
|
NATS_JETSTREAM_ENABLED=true
|
|
|
|
# SurrealDB (optional)
|
|
SURREAL_DB_URL=ws://surrealdb:8000
|
|
SURREAL_NAMESPACE=vapora
|
|
SURREAL_DATABASE=documents
|
|
|
|
# OpenTelemetry
|
|
OTEL_ENABLED=true
|
|
OTEL_JAEGER_ENDPOINT=http://jaeger:14268
|
|
OTEL_SERVICE_NAME=vapora-doc-lifecycle
|
|
|
|
# mTLS
|
|
MTLS_ENABLED=true
|
|
MTLS_SERVER_CERT=/etc/vapora/certs/server.crt
|
|
MTLS_SERVER_KEY=/etc/vapora/certs/server.key
|
|
MTLS_CA_CERT=/etc/vapora/certs/ca.crt
|
|
MTLS_ROTATION_DAYS=30
|
|
</code></pre>
|
|
<hr />
|
|
<h2 id="integration-checklist"><a class="header" href="#integration-checklist">Integration Checklist</a></h2>
|
|
<h3 id="immediate-ready-now"><a class="header" href="#immediate-ready-now">Immediate (Ready Now)</a></h3>
|
|
<ul>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
Core features (Phases 1-3)</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
VAPORA integration (Phase 4)</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
Production hardening (Phase 5)</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
Multi-agent support (Phase 6)</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
Enterprise features (Phase 7)</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
Kubernetes deployment</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
GraphQL API</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
WebSocket events</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
Distributed tracing</li>
|
|
<li><input disabled="" type="checkbox" checked=""/>
|
|
mTLS security</li>
|
|
</ul>
|
|
<h3 id="planned-phase-8"><a class="header" href="#planned-phase-8">Planned (Phase 8)</a></h3>
|
|
<ul>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Jaeger exporter</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
SurrealDB live testing</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Load testing</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Performance tuning</li>
|
|
<li><input disabled="" type="checkbox"/>
|
|
Production deployment guide</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h2>
|
|
<h3 id="common-issues"><a class="header" href="#common-issues">Common Issues</a></h3>
|
|
<p><strong>1. NATS Connection Failed</strong></p>
|
|
<pre><code class="language-bash"># Check NATS service
|
|
kubectl get svc -n doc-lifecycle
|
|
kubectl logs -n doc-lifecycle deployment/nats
|
|
</code></pre>
|
|
<p><strong>2. GraphQL Query Timeout</strong></p>
|
|
<pre><code class="language-bash"># Check semantic search performance
|
|
# Query execution should be < 200ms
|
|
# Check RAG index size
|
|
</code></pre>
|
|
<p><strong>3. WebSocket Disconnection</strong></p>
|
|
<pre><code class="language-bash"># Verify WebSocket port is open
|
|
# Check subscription history size
|
|
# Monitor event broadcast latency
|
|
</code></pre>
|
|
<hr />
|
|
<h2 id="references"><a class="header" href="#references">References</a></h2>
|
|
<p><strong>Documentation Files</strong>:</p>
|
|
<ul>
|
|
<li><code>/Tools/doc-lifecycle-manager/PHASE_7_COMPLETION.md</code> - Phase 7 details</li>
|
|
<li><code>/Tools/doc-lifecycle-manager/PHASES_COMPLETION.md</code> - All phases overview</li>
|
|
<li><code>/Tools/doc-lifecycle-manager/INTEGRATION_WITH_VAPORA.md</code> - Integration guide</li>
|
|
<li><code>/Tools/doc-lifecycle-manager/kubernetes/README.md</code> - K8s deployment</li>
|
|
</ul>
|
|
<p><strong>Source Code</strong>:</p>
|
|
<ul>
|
|
<li><code>crates/vapora-doc-lifecycle/src/lib.rs</code> - Main library</li>
|
|
<li><code>crates/vapora-doc-lifecycle/src/graphql_api.rs</code> - GraphQL resolver</li>
|
|
<li><code>crates/vapora-doc-lifecycle/src/websocket_events.rs</code> - WebSocket manager</li>
|
|
<li><code>crates/vapora-doc-lifecycle/src/mtls_auth.rs</code> - Security</li>
|
|
</ul>
|
|
<hr />
|
|
<h2 id="support"><a class="header" href="#support">Support</a></h2>
|
|
<p>For questions or issues:</p>
|
|
<ol>
|
|
<li>Check documentation in <code>/Tools/doc-lifecycle-manager/</code></li>
|
|
<li>Review test cases for usage examples</li>
|
|
<li>Check Kubernetes logs: <code>kubectl logs -n doc-lifecycle <pod></code></li>
|
|
<li>Monitor with Prometheus/Grafana</li>
|
|
</ol>
|
|
<hr />
|
|
<p><strong>Status</strong>: ✅ Ready for Production Deployment
|
|
<strong>Last Updated</strong>: 2025-11-10
|
|
<strong>Maintainer</strong>: VAPORA Team</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="../../integrations/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../../integrations/doc-lifecycle-integration.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="../../integrations/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next prefetch" href="../../integrations/doc-lifecycle-integration.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="../elasticlunr.min.js"></script>
|
|
<script src="../mark.min.js"></script>
|
|
<script src="../searcher.js"></script>
|
|
|
|
<script src="../clipboard.min.js"></script>
|
|
<script src="../highlight.js"></script>
|
|
<script src="../book.js"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|