diff --git a/docs/api/API.md b/docs/api/API.md new file mode 100644 index 0000000..c7cdc81 --- /dev/null +++ b/docs/api/API.md @@ -0,0 +1,1880 @@ +# Poimen Memory System — Complete API Reference with Response Formats + +**Last Updated**: 2025-01-30 +**Status**: ✅ Production Ready +**Total Endpoints**: 30+ +**Format**: JSON only + +--- + +## Table of Contents + +1. [Base Configuration](#base-configuration) +2. [Core Query Endpoints](#core-query-endpoints) +3. [Synthesis Endpoints](#synthesis-endpoints) +4. [Versioning Endpoints](#versioning-endpoints) +5. [Ranking Endpoints](#ranking-endpoints) +6. [Rebuild Endpoints](#rebuild-endpoints) +7. [Foundation Endpoints](#foundation-endpoints) +8. [Error Responses](#error-responses) +9. [Rate Limits](#rate-limits) + +--- + +## Base Configuration + +### URL +``` +http://localhost:8080 +``` + +### Authentication +``` +Authorization: Bearer +Content-Type: application/json +``` + +### Example Request Headers +```bash +curl -X POST http://localhost:8080/memory/query \ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ + -H "Content-Type: application/json" \ + -d '{...}' +``` + +--- + +## Core Query Endpoints + +### 1. Unified Query (Recommended) + +**Endpoint**: `POST /memory/query` + +**Request** +```json +{ + "query": "kubernetes debugging strategies", + "search_type": "entities", + "entity_type": "concept", + "confidence_floor": 0.5, + "top_k": 10, + "start_time": "2025-01-20T00:00:00Z", + "end_time": "2025-01-30T23:59:59Z", + "detect_communities": true, + "min_community_size": 3, + "find_paths": true, + "target_entity_id": "e_monitoring", + "max_path_depth": 5, + "k_hops": 2, + "discover_facets": true, + "facet_filters": { + "entity_types": ["concept", "technology"], + "confidence_level": "high", + "date_range": "this_month" + } +} +``` + +**Response (200 OK)** +```json +{ + "query": "kubernetes debugging strategies", + "search_type": "entities", + "execution_time_ms": 245, + "results": [ + { + "id": "e_k8s_debug_1", + "name": "Kubernetes Debugging Fundamentals", + "entity_type": "concept", + "similarity_score": 0.95, + "semantic_score": 0.95, + "lexical_score": 0.90, + "confidence": 0.92, + "created_at": "2025-01-15T08:30:00Z", + "updated_at": "2025-01-28T14:22:00Z", + "metadata": { + "source": "transcript://session-456", + "tags": ["kubernetes", "debugging", "operations"], + "community_id": 0 + } + }, + { + "id": "e_pod_logs_2", + "name": "Pod Logs Analysis", + "entity_type": "concept", + "similarity_score": 0.87, + "semantic_score": 0.92, + "lexical_score": 0.78, + "confidence": 0.85, + "created_at": "2025-01-10T10:15:00Z", + "updated_at": "2025-01-25T09:45:00Z", + "metadata": { + "source": "transcript://session-789", + "tags": ["logs", "troubleshooting"], + "community_id": 0 + } + } + ], + "total_count": 2, + "has_more": false, + "communities": { + "entity_count": 2, + "edge_count": 3, + "community_count": 1, + "total_modularity": 0.82, + "average_community_size": 2.0, + "communities": [ + { + "id": 0, + "entity_ids": ["e_k8s_debug_1", "e_pod_logs_2"], + "size": 2, + "modularity_contribution": 0.82, + "average_strength": 0.87, + "density": 1.0 + } + ] + }, + "paths": [ + { + "source_id": "e_k8s_debug_1", + "target_id": "e_monitoring", + "path_count": 1, + "shortest_distance": 2, + "average_distance": 2.0, + "paths_found": [ + { + "entity_ids": ["e_k8s_debug_1", "e_observability", "e_monitoring"], + "relation_types": ["related_to", "depends_on"], + "distance": 2, + "total_confidence": 0.92 + } + ] + } + ], + "available_facets": { + "entity_types": [ + { + "name": "concept", + "count": 42, + "percentage": 62.7 + }, + { + "name": "technology", + "count": 25, + "percentage": 37.3 + } + ], + "confidence_levels": [ + { + "name": "high", + "count": 52, + "percentage": 77.6 + }, + { + "name": "medium", + "count": 15, + "percentage": 22.4 + } + ], + "date_ranges": [ + { + "name": "this_month", + "count": 67, + "percentage": 100.0 + } + ], + "total_results": 67, + "facet_computation_ms": 45 + } +} +``` + +--- + +### 2. Semantic Search: Entities + +**Endpoint**: `POST /memory/query/semantic/entities` + +**Request** +```json +{ + "query": "debugging kubernetes pods", + "entity_type": "concept", + "confidence_floor": 0.6, + "top_k": 5 +} +``` + +**Response (200 OK)** +```json +{ + "query": "debugging kubernetes pods", + "search_type": "semantic_entities", + "execution_time_ms": 145, + "results": [ + { + "id": "e_k8s_debug_1", + "name": "Kubernetes Debugging Fundamentals", + "entity_type": "concept", + "similarity_score": 0.95, + "confidence": 0.92, + "metadata": { + "source": "transcript://session-456", + "tags": ["kubernetes", "debugging"], + "access_count": 23, + "last_accessed": "2025-01-28T15:30:00Z" + } + }, + { + "id": "e_pod_troubleshoot", + "name": "Pod Troubleshooting", + "entity_type": "concept", + "similarity_score": 0.88, + "confidence": 0.85, + "metadata": { + "source": "transcript://session-789", + "tags": ["pods", "troubleshooting"], + "access_count": 18, + "last_accessed": "2025-01-27T09:15:00Z" + } + } + ], + "total_count": 2, + "has_more": false +} +``` + +--- + +### 3. Semantic Search: Edges + +**Endpoint**: `POST /memory/query/semantic/edges` + +**Request** +```json +{ + "query": "depends on container runtime", + "relation_type": "depends_on", + "top_k": 5 +} +``` + +**Response (200 OK)** +```json +{ + "query": "depends on container runtime", + "search_type": "semantic_edges", + "execution_time_ms": 120, + "results": [ + { + "id": "edge_k8s_docker", + "source_entity_id": "e_kubernetes", + "source_name": "Kubernetes", + "target_entity_id": "e_docker", + "target_name": "Docker", + "relation_type": "depends_on", + "fact": "Kubernetes depends on Docker for containerization", + "similarity_score": 0.92, + "confidence": 0.88, + "created_at": "2025-01-15T08:30:00Z", + "metadata": { + "source": "transcript://session-456", + "evidence_count": 5 + } + }, + { + "id": "edge_k8s_containerd", + "source_entity_id": "e_kubernetes", + "source_name": "Kubernetes", + "target_entity_id": "e_containerd", + "target_name": "containerd", + "relation_type": "depends_on", + "fact": "Kubernetes can use containerd as container runtime", + "similarity_score": 0.85, + "confidence": 0.82, + "created_at": "2025-01-18T10:45:00Z", + "metadata": { + "source": "transcript://session-101", + "evidence_count": 3 + } + } + ], + "total_count": 2, + "has_more": false +} +``` + +--- + +### 4. Hybrid Search (Semantic + Lexical) + +**Endpoint**: `POST /memory/query/hybrid` + +**Request** +```json +{ + "query": "system design patterns microservices", + "semantic_weight": 0.6, + "lexical_weight": 0.4, + "top_k": 10 +} +``` + +**Response (200 OK)** +```json +{ + "query": "system design patterns microservices", + "search_type": "hybrid", + "execution_time_ms": 180, + "results": [ + { + "id": "e_microservices", + "name": "Microservices Architecture", + "entity_type": "concept", + "result_type": "entity", + "fused_score": 0.92, + "semantic_score": 0.95, + "lexical_score": 0.85, + "confidence": 0.89, + "metadata": { + "source": "transcript://session-200", + "tags": ["architecture", "design-patterns", "microservices"] + } + }, + { + "id": "edge_design_patterns", + "source_entity_id": "e_design_patterns", + "source_name": "Design Patterns", + "target_entity_id": "e_microservices", + "target_name": "Microservices", + "relation_type": "related_to", + "fact": "Design patterns apply to microservices architecture", + "result_type": "edge", + "fused_score": 0.88, + "semantic_score": 0.90, + "lexical_score": 0.82, + "confidence": 0.85, + "metadata": { + "source": "transcript://session-300", + "evidence_count": 7 + } + } + ], + "total_count": 2, + "has_more": false +} +``` + +--- + +## Synthesis Endpoints + +### 5. Entity Linking + +**Endpoint**: `POST /memory/synthesis/link-entities` + +**Request** +```json +{ + "project": "poimen", + "text": "Kubernetes and Docker are containerization technologies used for microservices." +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "text": "Kubernetes and Docker are containerization technologies used for microservices.", + "links": [ + { + "mention_text": "Kubernetes", + "start_offset": 0, + "end_offset": 10, + "entity_id": "e_kubernetes", + "entity_name": "Kubernetes", + "confidence": 0.99, + "match_type": "exact", + "reason": "Direct entity name match" + }, + { + "mention_text": "Docker", + "start_offset": 15, + "end_offset": 21, + "entity_id": "e_docker", + "entity_name": "Docker", + "confidence": 0.98, + "match_type": "exact", + "reason": "Direct entity name match" + } + ], + "unlinked_mentions": [ + { + "text": "containerization technologies", + "start_offset": 26, + "end_offset": 54, + "reason": "No matching entity found" + }, + { + "text": "microservices", + "start_offset": 69, + "end_offset": 82, + "reason": "Generic term, multiple possible matches" + } + ], + "total_mentions": 4, + "linked_count": 2, + "unlinked_count": 2, + "link_rate": 0.5, + "process_time_ms": 145 +} +``` + +--- + +### 6. Detect Aliases + +**Endpoint**: `POST /memory/synthesis/detect-aliases` + +**Request** +```json +{ + "project": "poimen", + "entity_id": "e_kubernetes", + "entity_name": "Kubernetes", + "text_samples": [ + "k8s is a container orchestrator", + "Kubernetes scales applications", + "k8s enables declarative configuration" + ] +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "entity_id": "e_kubernetes", + "entity_name": "Kubernetes", + "text_samples_processed": 3, + "aliases": [ + { + "alias": "k8s", + "frequency": 2, + "confidence": 0.95, + "first_seen": "2025-01-15T08:30:00Z", + "last_seen": "2025-01-28T14:22:00Z", + "evidence": [ + "k8s is a container orchestrator", + "k8s enables declarative configuration" + ] + } + ], + "alias_count": 1, + "total_aliases_found": 1, + "process_time_ms": 120 +} +``` + +--- + +### 7. Suggest Merges + +**Endpoint**: `POST /memory/synthesis/suggest-merges` + +**Request** +```json +{ + "project": "poimen", + "similarity_threshold": 0.8 +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "similarity_threshold": 0.8, + "suggestions": [ + { + "entity1_id": "e_k8s_v1", + "entity1_name": "Kubernetes v1", + "entity2_id": "e_k8s_v2", + "entity2_name": "Kubernetes v2", + "similarity_score": 0.95, + "confidence": 0.92, + "reasons": [ + "Name similarity (0.98)", + "Common related entities (5/6 shared)", + "Similar confidence levels (0.92 vs 0.90)", + "No contradictory facts" + ], + "merge_recommendation": "RECOMMENDED", + "merge_strategy": "Keep e_k8s_v1, merge e_k8s_v2 into it", + "impact": { + "entities_affected": 2, + "edges_affected": 8, + "estimated_time_ms": 45 + } + } + ], + "suggestion_count": 1, + "total_entities_scanned": 156, + "process_time_ms": 2340 +} +``` + +--- + +### 8. Detect Coreferences + +**Endpoint**: `POST /memory/synthesis/detect-coreferences` + +**Request** +```json +{ + "project": "poimen", + "texts": [ + "Kubernetes is great", + "k8s simplifies deployment", + "Kubernetes powers infrastructure" + ] +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "texts_processed": 3, + "clusters": [ + { + "entity_id": "e_kubernetes", + "canonical_name": "Kubernetes", + "mentions": [ + { + "text": "Kubernetes", + "occurrences": 2, + "confidence": 0.99 + }, + { + "text": "k8s", + "occurrences": 1, + "confidence": 0.95 + } + ], + "mention_count": 3, + "unique_mention_count": 2, + "confidence": 0.97, + "cluster_quality": "high" + } + ], + "cluster_count": 1, + "total_mentions": 3, + "mention_coverage": 1.0, + "process_time_ms": 180 +} +``` + +--- + +### 9. Inference Engine + +**Endpoint**: `POST /memory/synthesis/infer` + +**Request** +```json +{ + "project": "poimen", + "entity_id": "e_kubernetes", + "rules": [ + { + "id": "r1", + "antecedent": "depends_on", + "medial": null, + "consequent": "related_to", + "confidence_multiplier": 0.9, + "description": "If A depends_on B, then A related_to B" + }, + { + "id": "r2", + "antecedent": "uses", + "medial": "compatible_with", + "consequent": "can_replace", + "confidence_multiplier": 0.8, + "description": "If A uses B and B compatible_with C, then A can_replace B with C" + } + ], + "max_hops": 3 +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "entity_id": "e_kubernetes", + "entity_name": "Kubernetes", + "rules_applied": 2, + "inferred_facts": [ + { + "source_id": "e_kubernetes", + "source_name": "Kubernetes", + "target_id": "e_docker", + "target_name": "Docker", + "relation_type": "related_to", + "fact": "Kubernetes is related to Docker", + "confidence": 0.81, + "inference_rule": "r1", + "reasoning_chain": [ + { + "step": 1, + "relation": "depends_on", + "source": "e_kubernetes", + "target": "e_docker", + "confidence": 0.9 + } + ], + "is_new_fact": true, + "conflicts_with": [] + }, + { + "source_id": "e_kubernetes", + "source_name": "Kubernetes", + "target_id": "e_containerd", + "target_name": "containerd", + "relation_type": "can_replace", + "fact": "Kubernetes can use containerd instead of Docker", + "confidence": 0.72, + "inference_rule": "r2", + "reasoning_chain": [ + { + "step": 1, + "relation": "uses", + "source": "e_kubernetes", + "target": "e_docker", + "confidence": 0.88 + }, + { + "step": 2, + "relation": "compatible_with", + "source": "e_docker", + "target": "e_containerd", + "confidence": 0.82 + } + ], + "is_new_fact": true, + "conflicts_with": [] + } + ], + "fact_count": 2, + "new_fact_count": 2, + "conflict_count": 0, + "process_time_ms": 245 +} +``` + +--- + +### 10. Transitive Closure + +**Endpoint**: `POST /memory/synthesis/transitive-closure` + +**Request** +```json +{ + "project": "poimen", + "entity_id": "e_kubernetes", + "relation_type": "depends_on", + "max_hops": 3 +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "source_entity_id": "e_kubernetes", + "source_name": "Kubernetes", + "relation_type": "depends_on", + "max_hops": 3, + "closure": { + "reachable_count": 5, + "edge_count": 5, + "reachable": [ + { + "entity_id": "e_docker", + "entity_name": "Docker", + "relation_type": "depends_on", + "confidence": 0.95, + "distance": 1, + "path": ["e_kubernetes", "e_docker"], + "combined_confidence": 0.95 + }, + { + "entity_id": "e_linux", + "entity_name": "Linux", + "relation_type": "depends_on", + "confidence": 0.90, + "distance": 2, + "path": ["e_kubernetes", "e_docker", "e_linux"], + "combined_confidence": 0.855 + }, + { + "entity_id": "e_kernel", + "entity_name": "Kernel", + "relation_type": "depends_on", + "confidence": 0.85, + "distance": 3, + "path": ["e_kubernetes", "e_docker", "e_linux", "e_kernel"], + "combined_confidence": 0.727 + }, + { + "entity_id": "e_cgroups", + "entity_name": "cgroups", + "relation_type": "depends_on", + "confidence": 0.88, + "distance": 2, + "path": ["e_kubernetes", "e_docker", "e_cgroups"], + "combined_confidence": 0.836 + }, + { + "entity_id": "e_namespaces", + "entity_name": "namespaces", + "relation_type": "depends_on", + "confidence": 0.87, + "distance": 2, + "path": ["e_kubernetes", "e_docker", "e_namespaces"], + "combined_confidence": 0.8265 + } + ] + }, + "statistics": { + "avg_distance": 2.0, + "avg_confidence": 0.88, + "max_distance": 3, + "min_confidence": 0.85 + }, + "process_time_ms": 220 +} +``` + +--- + +### 11. Reasoning Paths + +**Endpoint**: `POST /memory/synthesis/reasoning-paths` + +**Request** +```json +{ + "project": "poimen", + "source_id": "e_kubernetes", + "target_id": "e_linux", + "max_hops": 5 +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "source_id": "e_kubernetes", + "source_name": "Kubernetes", + "target_id": "e_linux", + "target_name": "Linux", + "paths": [ + { + "path_id": 0, + "entity_ids": ["e_kubernetes", "e_docker", "e_linux"], + "entity_names": ["Kubernetes", "Docker", "Linux"], + "relations": ["depends_on", "runs_on"], + "confidence_scores": [0.95, 0.92], + "distance": 2, + "total_confidence": 0.874, + "path_type": "direct" + }, + { + "path_id": 1, + "entity_ids": ["e_kubernetes", "e_container", "e_linux"], + "entity_names": ["Kubernetes", "Container", "Linux"], + "relations": ["uses", "requires"], + "confidence_scores": [0.88, 0.90], + "distance": 2, + "total_confidence": 0.792, + "path_type": "direct" + }, + { + "path_id": 2, + "entity_ids": ["e_kubernetes", "e_docker", "e_kernel", "e_linux"], + "entity_names": ["Kubernetes", "Docker", "Kernel", "Linux"], + "relations": ["depends_on", "requires", "runs_on"], + "confidence_scores": [0.95, 0.85, 0.93], + "distance": 3, + "total_confidence": 0.749, + "path_type": "indirect" + } + ], + "path_count": 3, + "statistics": { + "shortest_path_distance": 2, + "average_path_distance": 2.33, + "best_path_confidence": 0.874, + "average_path_confidence": 0.805 + }, + "process_time_ms": 320 +} +``` + +--- + +### 12. Query Reasoning + +**Endpoint**: `POST /memory/synthesis/reason` + +**Request** +```json +{ + "project": "poimen", + "question": "Why does Kubernetes depend on Docker for containerization?" +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "question": "Why does Kubernetes depend on Docker for containerization?", + "question_type": "causal", + "answers": [ + "Container isolation", + "Standardized runtime", + "Resource efficiency", + "Portable packaging" + ], + "confidence": 0.87, + "reasoning_steps": [ + { + "step_id": 1, + "question": "Why does Kubernetes depend on Docker for containerization?", + "search_type": "causal", + "results": [ + "Container isolation", + "Standardized runtime" + ], + "confidence": 0.90, + "constraints_satisfied": 0, + "execution_time_ms": 120 + }, + { + "step_id": 2, + "question": "What are the benefits of containerization?", + "search_type": "setquery", + "results": [ + "Resource efficiency", + "Portable packaging" + ], + "confidence": 0.84, + "constraints_satisfied": 0, + "execution_time_ms": 95 + } + ], + "explanation": "Found 4 answer(s) through 2 reasoning step(s): Step 1: Why does Kubernetes depend on Docker? (confidence: 0.90). Step 2: What are the benefits of containerization? (confidence: 0.84).", + "supportive_entities": [ + { + "entity_id": "e_docker", + "entity_name": "Docker", + "relevance": 0.95, + "reasoning": "Direct dependency target" + }, + { + "entity_id": "e_containerization", + "entity_name": "Containerization", + "relevance": 0.88, + "reasoning": "Core concept" + } + ], + "contradicting_entities": [], + "process_time_ms": 450 +} +``` + +--- + +### 13. Summarization + +**Endpoint**: `POST /memory/synthesis/summarize` + +**Request** +```json +{ + "project": "poimen", + "content": "Kubernetes is a container orchestration platform. Docker is used for containerization. Kubernetes manages Docker containers at scale. Microservices are the primary use case. Load balancing and auto-scaling are key features. Declarative configuration enables easy management.", + "max_length": 150, + "strategy": "hybrid" +} +``` + +**Response (200 OK)** +```json +{ + "project": "poimen", + "original_length": 318, + "original_word_count": 44, + "summary": "Kubernetes is a container orchestration platform that manages Docker containers at scale. Load balancing, auto-scaling, and declarative configuration enable microservices deployment.", + "summary_length": 146, + "summary_word_count": 22, + "compression_ratio": 0.46, + "key_facts": [ + { + "fact": "Kubernetes", + "importance": 0.98, + "fact_type": "entity", + "frequency": 2 + }, + { + "fact": "Docker", + "importance": 0.95, + "fact_type": "entity", + "frequency": 2 + }, + { + "fact": "Auto-scaling", + "importance": 0.88, + "fact_type": "feature", + "frequency": 1 + }, + { + "fact": "Load balancing", + "importance": 0.87, + "fact_type": "feature", + "frequency": 1 + }, + { + "fact": "Declarative configuration", + "importance": 0.85, + "fact_type": "feature", + "frequency": 1 + } + ], + "coherence_score": 0.89, + "coherence_breakdown": { + "flow": 0.87, + "entity_consistency": 0.92, + "vocabulary_richness": 0.88, + "informativeness": 0.85 + }, + "strategy_used": "hybrid", + "process_time_ms": 220 +} +``` + +--- + +## Versioning Endpoints + +### 14. Get Entity Versions + +**Endpoint**: `GET /memory/entities/{id}/versions` + +**Response (200 OK)** +```json +{ + "entity_id": "e_kubernetes", + "entity_name": "Kubernetes", + "versions": [ + { + "version_num": 1, + "operation": "CREATE", + "snapshot": { + "name": "Kubernetes", + "entity_type": "technology", + "confidence": 0.85 + }, + "changed_at": "2025-01-15T08:30:00Z", + "changed_by": "user@example.com", + "fields_changed": ["name", "entity_type", "confidence"] + }, + { + "version_num": 2, + "operation": "UPDATE", + "snapshot": { + "name": "Kubernetes", + "entity_type": "technology", + "confidence": 0.92 + }, + "changed_at": "2025-01-22T14:15:00Z", + "changed_by": "analyst@example.com", + "fields_changed": ["confidence"] + }, + { + "version_num": 3, + "operation": "UPDATE", + "snapshot": { + "name": "Kubernetes", + "entity_type": "technology", + "confidence": 0.95, + "description": "Container orchestration platform" + }, + "changed_at": "2025-01-28T10:45:00Z", + "changed_by": "expert@example.com", + "fields_changed": ["confidence", "description"] + } + ], + "total_versions": 3, + "current_version": 3 +} +``` + +--- + +### 15. Get Specific Entity Version + +**Endpoint**: `GET /memory/entities/{id}/versions/{num}` + +**Response (200 OK)** +```json +{ + "entity_id": "e_kubernetes", + "version_num": 2, + "operation": "UPDATE", + "snapshot": { + "id": "e_kubernetes", + "name": "Kubernetes", + "entity_type": "technology", + "confidence": 0.92, + "created_at": "2025-01-15T08:30:00Z", + "metadata": { + "source": "transcript://session-123", + "tags": ["orchestration", "containers"] + } + }, + "changed_at": "2025-01-22T14:15:00Z", + "changed_by": "analyst@example.com", + "fields_changed": ["confidence"], + "change_summary": "Updated confidence from 0.85 to 0.92" +} +``` + +--- + +### 16. Entity Diff + +**Endpoint**: `POST /memory/entities/diff` + +**Request** +```json +{ + "entity_id": "e_kubernetes", + "from_version": 1, + "to_version": 3 +} +``` + +**Response (200 OK)** +```json +{ + "entity_id": "e_kubernetes", + "from_version": 1, + "to_version": 3, + "version_span": 2, + "diff": { + "added_fields": { + "description": "Container orchestration platform" + }, + "removed_fields": {}, + "modified_fields": { + "confidence": { + "old": 0.85, + "new": 0.95, + "change_percent": 11.8 + } + } + }, + "change_timeline": [ + { + "version": 1, + "confidence": 0.85, + "changed_at": "2025-01-15T08:30:00Z" + }, + { + "version": 2, + "confidence": 0.92, + "changed_at": "2025-01-22T14:15:00Z" + }, + { + "version": 3, + "confidence": 0.95, + "changed_at": "2025-01-28T10:45:00Z" + } + ], + "editors_involved": ["user@example.com", "analyst@example.com", "expert@example.com"], + "total_changes": 2 +} +``` + +--- + +### 17. Point-in-Time Query + +**Endpoint**: `GET /memory/entities/at?as_of=2025-01-22T15:00:00Z` + +**Response (200 OK)** +```json +{ + "as_of_time": "2025-01-22T15:00:00Z", + "query_time_relative": "-6 days", + "entities": [ + { + "entity_id": "e_kubernetes", + "name": "Kubernetes", + "entity_type": "technology", + "confidence": 0.92, + "version": 2, + "snapshot": { + "name": "Kubernetes", + "entity_type": "technology", + "confidence": 0.92 + }, + "was_valid_at_time": true, + "changed_after": { + "version": 3, + "changed_at": "2025-01-28T10:45:00Z", + "change": "confidence: 0.92 → 0.95" + } + }, + { + "entity_id": "e_docker", + "name": "Docker", + "entity_type": "technology", + "confidence": 0.88, + "version": 1, + "snapshot": { + "name": "Docker", + "entity_type": "technology", + "confidence": 0.88 + }, + "was_valid_at_time": true, + "changed_after": null + } + ], + "total_entities": 2, + "entities_created_since": 0, + "entities_modified_since": 1, + "entities_deleted_since": 0 +} +``` + +--- + +## Ranking Endpoints + +### 18. Get Ranking Profiles + +**Endpoint**: `GET /memory/ranking/profiles` + +**Response (200 OK)** +```json +{ + "profiles": [ + { + "name": "default", + "description": "Balanced ranking across all signals", + "is_default": true, + "signals": { + "semantic": { + "weight": 0.40, + "description": "Vector similarity to query" + }, + "lexical": { + "weight": 0.25, + "description": "BM25 keyword matching" + }, + "recency": { + "weight": 0.15, + "description": "Exponential decay by age (30d half-life)" + }, + "frequency": { + "weight": 0.10, + "description": "Logarithmic access count" + }, + "confidence": { + "weight": 0.05, + "description": "Base confidence decay (90d half-life)" + }, + "community": { + "weight": 0.03, + "description": "Community size + activity" + }, + "contradiction": { + "weight": 0.02, + "description": "Penalty for unresolved conflicts" + } + }, + "weights_sum": 1.0, + "recommended_for": ["general queries", "balanced results"] + }, + { + "name": "recency_focused", + "description": "Prioritize recent discoveries and updates", + "is_default": false, + "signals": { + "semantic": { + "weight": 0.30, + "description": "Vector similarity to query" + }, + "lexical": { + "weight": 0.20, + "description": "BM25 keyword matching" + }, + "recency": { + "weight": 0.35, + "description": "Exponential decay by age (20d half-life)" + }, + "frequency": { + "weight": 0.08, + "description": "Logarithmic access count" + }, + "confidence": { + "weight": 0.04, + "description": "Base confidence decay" + }, + "community": { + "weight": 0.02, + "description": "Community size + activity" + }, + "contradiction": { + "weight": 0.01, + "description": "Penalty for unresolved conflicts" + } + }, + "weights_sum": 1.0, + "recommended_for": ["breaking news", "trending topics", "live monitoring"] + }, + { + "name": "accuracy_focused", + "description": "Prioritize high-confidence and well-supported results", + "is_default": false, + "signals": { + "semantic": { + "weight": 0.35, + "description": "Vector similarity to query" + }, + "lexical": { + "weight": 0.25, + "description": "BM25 keyword matching" + }, + "recency": { + "weight": 0.08, + "description": "Exponential decay by age (60d half-life)" + }, + "frequency": { + "weight": 0.10, + "description": "Logarithmic access count" + }, + "confidence": { + "weight": 0.15, + "description": "Base confidence decay (120d half-life)" + }, + "community": { + "weight": 0.05, + "description": "Community size + activity" + }, + "contradiction": { + "weight": 0.02, + "description": "Penalty for unresolved conflicts" + } + }, + "weights_sum": 1.0, + "recommended_for": ["critical decisions", "compliance", "audits"] + } + ], + "total_profiles": 3, + "available_custom_profiles": false +} +``` + +--- + +### 19. Query with Ranking Profile + +**Endpoint**: `POST /memory/query` with `ranking_profile` + +**Request** +```json +{ + "query": "kubernetes debugging", + "ranking_profile": "recency_focused", + "top_k": 5 +} +``` + +**Response (200 OK)** +```json +{ + "query": "kubernetes debugging", + "ranking_profile": "recency_focused", + "execution_time_ms": 185, + "results": [ + { + "id": "e_k8s_debug_latest", + "name": "Latest K8s Debugging Techniques (2025-01-28)", + "entity_type": "concept", + "fused_score": 0.91, + "scores": { + "semantic": 0.88, + "lexical": 0.85, + "recency": 0.98, + "frequency": 0.65, + "confidence": 0.90, + "community": 0.82, + "contradiction": 1.0 + }, + "weighted_score": 0.91, + "confidence": 0.90, + "created_at": "2025-01-28T10:30:00Z", + "updated_at": "2025-01-28T14:22:00Z", + "days_old": 0, + "access_count": 12 + }, + { + "id": "e_pod_logs_2", + "name": "Pod Logs Analysis", + "entity_type": "concept", + "fused_score": 0.85, + "scores": { + "semantic": 0.92, + "lexical": 0.78, + "recency": 0.82, + "frequency": 0.70, + "confidence": 0.85, + "community": 0.88, + "contradiction": 1.0 + }, + "weighted_score": 0.85, + "confidence": 0.85, + "created_at": "2025-01-25T09:45:00Z", + "updated_at": "2025-01-27T11:30:00Z", + "days_old": 3, + "access_count": 18 + } + ], + "total_count": 2, + "scoring_note": "Results ranked using 'recency_focused' profile (recency weight: 35%)" +} +``` + +--- + +## Rebuild Endpoints + +### 20. Rebuild Memory + +**Endpoint**: `POST /memory/rebuild` + +**Request** +```json +{ + "project": "poimen", + "dry_run": false, + "verify_parity": true, + "from_checkpoint": null +} +``` + +**Response (200 OK)** +```json +{ + "status": "success", + "phase": "completed", + "project": "poimen", + "dry_run": false, + "records_processed": 542, + "records_skipped": 0, + "errors": 0, + "total_time_ms": 8234, + "rebuild_duration": "8s 234ms", + "records_per_second": 65.8, + "checksum_before": "abc123def456789abc123def456789ab", + "checksum_after": "abc123def456789abc123def456789ab", + "checksum_match": true, + "parity_verified": true, + "parity_checks": [ + { + "check_id": "M2.8_rebuild_parity", + "name": "Rebuild Parity Check", + "status": "PASS", + "details": "Checksums match after rebuild" + }, + { + "check_id": "entity_count", + "name": "Entity Count Verification", + "status": "PASS", + "before": 156, + "after": 156 + }, + { + "check_id": "edge_count", + "name": "Edge Count Verification", + "status": "PASS", + "before": 342, + "after": 342 + } + ], + "rebuild_path": "from_event_log", + "event_log_entries_read": 542, + "event_log_entries_deduplicated": 0, + "timestamp": "2025-01-30T02:00:00Z" +} +``` + +--- + +### 21. Rebuild Status + +**Endpoint**: `GET /memory/rebuild/status` + +**Response (200 OK)** +```json +{ + "status": "idle", + "current_phase": null, + "last_rebuild": { + "started_at": "2025-01-29T02:00:00Z", + "completed_at": "2025-01-29T02:00:08Z", + "total_time_ms": 8234, + "status": "success", + "records_processed": 542, + "errors": 0, + "checksum_match": true + }, + "next_scheduled_rebuild": "2025-01-30T02:00:00Z", + "rebuild_schedule": "daily", + "rebuild_schedule_utc": "02:00 UTC", + "statistics": { + "total_rebuilds": 127, + "successful_rebuilds": 127, + "failed_rebuilds": 0, + "checksum_mismatch_count": 0, + "average_rebuild_time_ms": 7845, + "last_7_days_success_rate": 1.0, + "last_30_days_success_rate": 1.0 + } +} +``` + +--- + +## Foundation Endpoints + +### 22. Ingest Record + +**Endpoint**: `POST /memory/ingest` + +**Request** +```json +{ + "project": "poimen", + "source": "transcript://session-123", + "kind": "L1", + "text": "Kubernetes port 8080 conflict resolved by checking service definition and updating containerPort mapping.", + "metadata": { + "session_id": "sess-123", + "topic": "troubleshooting", + "severity": "medium", + "user": "devops-team" + } +} +``` + +**Response (201 Created)** +```json +{ + "id": "chunk-abc123def456", + "project": "poimen", + "source": "transcript://session-123", + "kind": "L1", + "sha256": "de12cd34ef56789abc123def456789ab", + "queue_status": "pending", + "idempotency_key": "sess-123:0", + "timestamp": "2025-01-30T10:15:00Z", + "processing": { + "status": "queued", + "entity_extraction": { + "status": "pending", + "estimated_entities": 0 + }, + "fact_extraction": { + "status": "pending", + "estimated_facts": 0 + }, + "contradiction_detection": { + "status": "pending", + "estimated_contradictions": 0 + } + } +} +``` + +--- + +### 23. Context Retrieval + +**Endpoint**: `POST /memory/context` + +**Request** +```json +{ + "project": "poimen", + "tool": "kubectl", + "task": "debug-pod", + "signature_source": "failure_log", + "scope": "tool_context", + "budget": 8192 +} +``` + +**Response (200 OK)** +```json +{ + "tier": 1, + "project": "poimen", + "tool": "kubectl", + "task": "debug-pod", + "retrieval_time_ms": 125, + "lessons": [ + { + "tier": 1, + "level": "L1", + "score": 1.0, + "text": "Pod in CrashLoopBackOff: check logs with kubectl logs and review container exit codes.", + "matched_kind": "signature", + "entity_confidence": 0.95, + "seen_count": 23, + "last_seen": "2025-01-28T15:30:00Z", + "source": "transcript://session-456", + "size_bytes": 165 + }, + { + "tier": 2, + "level": "L2", + "score": 0.87, + "text": "Common Kubernetes debugging patterns: check events (kubectl describe), inspect YAML, verify resource limits, review node status.", + "matched_kind": "semantic_search", + "entity_confidence": 0.82, + "seen_count": 15, + "last_seen": "2025-01-25T09:15:00Z", + "source": "transcript://session-789", + "size_bytes": 198 + }, + { + "tier": 3, + "level": "R", + "score": 0.65, + "text": "kubectl Troubleshooting Guide: See official Kubernetes debugging documentation for comprehensive reference.", + "matched_kind": "reference", + "source": "obsidian://poimen-vault/kubectl.md", + "size_bytes": 145 + } + ], + "skills": [ + { + "name": "diagnose-pod-failure", + "description": "Diagnose Kubernetes pod CrashLoopBackOff failures", + "why_suggested": "Tier-1 signature matched", + "confidence": 0.98 + }, + { + "name": "analyze-container-logs", + "description": "Analyze container logs using kubectl", + "why_suggested": "Tier-2 semantic match", + "confidence": 0.85 + } + ], + "budget": { + "requested": 8192, + "used": 508, + "remaining": 7684, + "dropped": 0, + "degradation": null + } +} +``` + +--- + +### 24. Health Check + +**Endpoint**: `GET /health` + +**Response (200 OK)** +```json +{ + "status": "ok", + "timestamp": "2025-01-30T10:15:00Z", + "service": "poimen-memory", + "version": "1.0.0", + "uptime_seconds": 86400, + "dependencies": { + "postgres": { + "status": "ok", + "response_time_ms": 2, + "pool_size": 10, + "active_connections": 3 + }, + "opensearch": { + "status": "ok", + "response_time_ms": 5, + "cluster_health": "green", + "active_shards": 30 + }, + "obsidian": { + "status": "ok", + "response_time_ms": 45, + "vault_files": 156 + } + } +} +``` + +--- + +## Error Responses + +### 400 Bad Request + +```json +{ + "error": "Bad Request", + "code": "INVALID_PARAMETER", + "message": "Query is required and must be between 1 and 2000 characters", + "details": { + "field": "query", + "issue": "empty_string", + "min_length": 1, + "max_length": 2000 + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +### 401 Unauthorized + +```json +{ + "error": "Unauthorized", + "code": "MISSING_AUTH", + "message": "Missing or invalid JWT bearer token", + "details": { + "provided": null, + "expected": "Bearer " + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +### 403 Forbidden + +```json +{ + "error": "Forbidden", + "code": "INSUFFICIENT_PERMISSIONS", + "message": "Token lacks required permission", + "details": { + "required_permission": "memory:write", + "user_permissions": ["memory:read"], + "contact_admin": "admin@example.com" + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +### 404 Not Found + +```json +{ + "error": "Not Found", + "code": "RESOURCE_NOT_FOUND", + "message": "Entity not found", + "details": { + "entity_id": "e_nonexistent", + "searched_in": ["memory_entity"], + "similar_entities": ["e_kubernetes", "e_container"] + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +### 409 Conflict + +```json +{ + "error": "Conflict", + "code": "REBUILD_PARITY_FAILED", + "message": "Checksum mismatch after rebuild", + "details": { + "checksum_before": "abc123...", + "checksum_after": "xyz789...", + "gate": "M2.8_rebuild_parity", + "suggestion": "Investigate event log for corruption" + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +### 429 Too Many Requests + +```json +{ + "error": "Too Many Requests", + "code": "RATE_LIMIT_EXCEEDED", + "message": "Rate limit exceeded for this endpoint", + "details": { + "endpoint": "/memory/query", + "limit": 500, + "window": "hour", + "reset_at": "2025-01-30T11:15:00Z", + "retry_after_seconds": 3600 + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +### 503 Service Unavailable + +```json +{ + "error": "Service Unavailable", + "code": "DEPENDENCY_DOWN", + "message": "OpenSearch cluster is unavailable", + "details": { + "dependency": "opensearch", + "status": "down", + "last_check": "2025-01-30T10:14:55Z", + "retry_after_seconds": 30 + }, + "timestamp": "2025-01-30T10:15:00Z" +} +``` + +--- + +## Rate Limits + +``` +Per API Key Per Hour: +├─ Query (POST /memory/query) 500 req/hr +├─ Semantic Search 500 req/hr +├─ Ingest (POST /memory/ingest) 100 req/hr +├─ Context (POST /memory/context) 100 req/hr +├─ Versioning Endpoints 200 req/hr +├─ Ranking Endpoints 500 req/hr +├─ Rebuild (POST /memory/rebuild) 10 req/hr +├─ Synthesis: link-entities 100 req/hr +├─ Synthesis: detect-aliases 100 req/hr +├─ Synthesis: suggest-merges 50 req/hr (compute-intensive) +├─ Synthesis: detect-coreferences 100 req/hr +├─ Synthesis: infer 50 req/hr (compute-intensive) +├─ Synthesis: transitive-closure 50 req/hr +├─ Synthesis: reasoning-paths 100 req/hr +├─ Synthesis: reason 50 req/hr (reasoning-intensive) +└─ Synthesis: summarize 100 req/hr +``` + +--- + +## Frontend Integration Guide + +### 1. Setup Bearer Token + +```javascript +const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."; +const headers = { + "Authorization": `Bearer ${jwt}`, + "Content-Type": "application/json" +}; +``` + +### 2. Query with Error Handling + +```javascript +async function query(q) { + try { + const res = await fetch("http://localhost:8080/memory/query", { + method: "POST", + headers, + body: JSON.stringify({ + query: q, + search_type: "entities", + top_k: 10 + }) + }); + + if (!res.ok) { + const err = await res.json(); + console.error(`[${err.code}] ${err.message}`); + return null; + } + + return await res.json(); + } catch (e) { + console.error("Network error:", e); + return null; + } +} +``` + +### 3. Parse Versioning Response + +```javascript +async function getEntityHistory(entityId) { + const res = await fetch( + `http://localhost:8080/memory/entities/${entityId}/versions`, + { headers } + ); + const data = await res.json(); + + // Timeline visualization + const timeline = data.versions.map(v => ({ + time: new Date(v.changed_at), + version: v.version_num, + editor: v.changed_by, + changes: v.fields_changed + })); + + return timeline; +} +``` + +### 4. Rank with Multi-Signal Profile + +```javascript +async function rankedQuery(q, profile = "default") { + const res = await fetch("http://localhost:8080/memory/query", { + method: "POST", + headers, + body: JSON.stringify({ + query: q, + ranking_profile: profile, + top_k: 10 + }) + }); + return await res.json(); +} +``` + +--- + +**Status**: ✅ All API endpoints documented with complete JSON response formats for frontend integration.