mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-08-07 14:08:43 -04:00
4798 lines
140 KiB
JSON
4798 lines
140 KiB
JSON
[
|
|
{
|
|
"id": "CHAT-001",
|
|
"domain": "chat",
|
|
"name": "Core Chat Streaming & SSE Message Generation",
|
|
"purpose": "Handles real-time Server-Sent Events (SSE) chat streaming, token rendering, and model response generation.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chatStream.js",
|
|
"static/js/chat.js",
|
|
"static/js/streamingRenderer.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/chat_routes.py:chat_stream",
|
|
"routes/chat_helpers.py:build_chat_context",
|
|
"src/chat_handler.py:ChatHandler.preprocess_message",
|
|
"src/chat_processor.py:ChatProcessor.build_context_preface",
|
|
"src/llm_core.py:stream_llm_with_fallback",
|
|
"src/agent_loop.py:stream_agent_loop"
|
|
],
|
|
"routes": [
|
|
"/api/chat_stream",
|
|
"/api/chat"
|
|
],
|
|
"configuration": [
|
|
"OPENAI_API_KEY",
|
|
"OLLAMA_BASE_URL",
|
|
"REQUEST_TIMEOUT"
|
|
],
|
|
"persistence": [
|
|
"SESSIONS_FILE",
|
|
"DATA_DIR/sessions/"
|
|
],
|
|
"dependencies": [
|
|
"fastapi",
|
|
"starlette.responses.StreamingResponse",
|
|
"httpx"
|
|
],
|
|
"tests": [
|
|
"tests/test_chat_metrics.py",
|
|
"tests/test_resend_message_nondestructive.py"
|
|
],
|
|
"documentation": [
|
|
"docs/chat.webm",
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Stream interruption on connection drops requires retry logic."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/chat_routes.py",
|
|
"symbol": "chat_stream",
|
|
"line_range": "L702-L1870",
|
|
"explanation": "POST /api/chat_stream SSE endpoint; builds the shared chat context, then dispatches to the chat-mode or agent-mode streaming path."
|
|
},
|
|
{
|
|
"path": "routes/chat_helpers.py",
|
|
"symbol": "build_chat_context",
|
|
"line_range": "L669-L863",
|
|
"explanation": "Shared context builder invoked by chat_stream; runs message preprocessing and assembles the memory/RAG/web context preface."
|
|
},
|
|
{
|
|
"path": "src/chat_handler.py",
|
|
"symbol": "ChatHandler.preprocess_message",
|
|
"line_range": "L123-L315",
|
|
"explanation": "Message preprocessing (attachments, URLs, tool preprocessing) reached from build_chat_context via routes/chat_helpers.py:preprocess."
|
|
},
|
|
{
|
|
"path": "src/chat_processor.py",
|
|
"symbol": "ChatProcessor.build_context_preface",
|
|
"line_range": "L263-L493",
|
|
"explanation": "Builds the retrieval and web-source context preface injected into the streamed request."
|
|
},
|
|
{
|
|
"path": "src/llm_core.py",
|
|
"symbol": "stream_llm_with_fallback",
|
|
"line_range": "L2794-L2895",
|
|
"explanation": "Chat-mode streaming dispatcher called from chat_stream; wraps stream_llm with an ordered provider fallback chain."
|
|
},
|
|
{
|
|
"path": "src/llm_core.py",
|
|
"symbol": "stream_llm",
|
|
"line_range": "L2131-L2151",
|
|
"explanation": "Per-request streaming entry wrapped by stream_llm_with_fallback; acquires the local model slot and delegates to _stream_llm_inner."
|
|
},
|
|
{
|
|
"path": "src/agent_loop.py",
|
|
"symbol": "stream_agent_loop",
|
|
"line_range": "L3079-L5248",
|
|
"explanation": "Agent-mode streaming path called from chat_stream when the request selects agent mode."
|
|
},
|
|
{
|
|
"path": "tests/test_chat_metrics.py",
|
|
"symbol": "test_stream_llm_passes_through_llamacpp_timings",
|
|
"line_range": "L129-L136",
|
|
"explanation": "Inspected unit test asserting stream_llm forwards backend generation timings into the emitted metrics chunk."
|
|
},
|
|
{
|
|
"path": "tests/test_resend_message_nondestructive.py",
|
|
"symbol": "test_resend_message_does_not_truncate_by_default",
|
|
"line_range": "L23-L36",
|
|
"explanation": "Inspected unit test asserting the frontend resend path does not truncate prior conversation turns."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E2",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires access to a live LLM provider endpoint (OpenAI API key or local Ollama server)."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-002",
|
|
"domain": "chat",
|
|
"name": "Session Management & Conversation State",
|
|
"purpose": "Manages session creation, listing, switching, renaming, and persistence of conversation metadata.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/sessions.js",
|
|
"static/js/sidebar-layout.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/session_routes.py:setup_session_routes",
|
|
"core/session_manager.py:SessionManager"
|
|
],
|
|
"routes": [
|
|
"/api/sessions",
|
|
"/api/sessions/{session_id}"
|
|
],
|
|
"configuration": [
|
|
"SESSIONS_FILE",
|
|
"DATA_DIR/odysseus.db"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/sessions.json",
|
|
"SQLite session table"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3",
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_session_manager.py",
|
|
"tests/test_session_routes_utcnow.py"
|
|
],
|
|
"documentation": [
|
|
"docs/setup.md"
|
|
],
|
|
"risks": [
|
|
"Concurrent file writes to sessions.json under high load."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/session_routes.py",
|
|
"symbol": "@router.get('/api/sessions')",
|
|
"line_range": "L150-L210",
|
|
"explanation": "Lists active sessions filtered by user owner scope."
|
|
},
|
|
{
|
|
"path": "core/session_manager.py",
|
|
"symbol": "SessionManager",
|
|
"line_range": "L30-L150",
|
|
"explanation": "Provides thread-safe session storage operations."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-003",
|
|
"domain": "chat",
|
|
"name": "Chat History & Message Editing/Truncation",
|
|
"purpose": "Provides history retrieval, message content updating, message deletion, and history branch truncation.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chat.js",
|
|
"static/js/sessions.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/history/history_routes.py:setup_history_routes"
|
|
],
|
|
"routes": [
|
|
"/api/history/{session_id}",
|
|
"/api/session/{session_id}/truncate",
|
|
"/api/session/{session_id}/edit-message"
|
|
],
|
|
"configuration": [
|
|
"MAX_HISTORY_MESSAGES"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/sessions/"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3",
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/test_history_db_fallback_hidden.py",
|
|
"tests/test_truncate_message_count_regression.py"
|
|
],
|
|
"documentation": [
|
|
"docs/attachments.md"
|
|
],
|
|
"risks": [
|
|
"Truncating messages re-indexes context window and clears cached tool calls."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/history/history_routes.py",
|
|
"symbol": "@router.get('/api/history/{session_id}')",
|
|
"line_range": "L178-L230",
|
|
"explanation": "Fetches message history timeline for a session."
|
|
},
|
|
{
|
|
"path": "routes/history_routes.py",
|
|
"symbol": "_sys.modules[__name__] = _canonical",
|
|
"line_range": "L1-L17",
|
|
"explanation": "Backward-compatibility shim module."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-004",
|
|
"domain": "chat",
|
|
"name": "File & Multimodal Attachment Handling",
|
|
"purpose": "Handles uploading, mime validation, image preview, vision encoding, and file attachments in chat messages.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/fileHandler.js",
|
|
"static/js/chat.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/upload_routes.py:setup_upload_routes",
|
|
"src/upload_handler.py:UploadHandler"
|
|
],
|
|
"routes": [
|
|
"/api/upload",
|
|
"/api/upload/{file_id}/vision",
|
|
"/api/upload/cleanup"
|
|
],
|
|
"configuration": [
|
|
"MAX_UPLOAD_SIZE_MB",
|
|
"ALLOWED_UPLOAD_EXTENSIONS"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/uploads/"
|
|
],
|
|
"dependencies": [
|
|
"pillow",
|
|
"python-magic"
|
|
],
|
|
"tests": [
|
|
"tests/test_upload_handler_atomicity.py",
|
|
"tests/test_upload_routes_owner_scope.py"
|
|
],
|
|
"documentation": [
|
|
"docs/attachments.md"
|
|
],
|
|
"risks": [
|
|
"Large file uploads may consume server disk space if cleanup task fails."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/upload_routes.py",
|
|
"symbol": "@router.post('')",
|
|
"line_range": "L257-L310",
|
|
"explanation": "Accepts multi-part file uploads and generates vision metadata."
|
|
},
|
|
{
|
|
"path": "src/upload_handler.py",
|
|
"symbol": "UploadHandler.save_file",
|
|
"line_range": "L50-L140",
|
|
"explanation": "Validates upload size and atomicity on disk."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-005",
|
|
"domain": "chat",
|
|
"name": "Chat Message Search",
|
|
"purpose": "Enables full-text keyword search across stored chat messages and sessions.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/search-chat.js",
|
|
"static/js/search.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/search_routes.py:setup_search_routes",
|
|
"src/session_search.py:search_sessions"
|
|
],
|
|
"routes": [
|
|
"/api/search/chat"
|
|
],
|
|
"configuration": [
|
|
"SEARCH_INDEX_CACHE_TTL"
|
|
],
|
|
"persistence": [
|
|
"SQLite FTS / session indices"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_session_search.py",
|
|
"tests/test_session_search_batch_fetch.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Full table scans on un-indexed text columns for very large databases."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/search_routes.py",
|
|
"symbol": "setup_search_routes",
|
|
"line_range": "L30-L80",
|
|
"explanation": "Registers chat message search endpoint."
|
|
},
|
|
{
|
|
"path": "src/session_search.py",
|
|
"symbol": "search_sessions",
|
|
"line_range": "L20-L90",
|
|
"explanation": "Executes query matching against session transcripts."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-006",
|
|
"domain": "chat",
|
|
"name": "System Prompts & Preset Management",
|
|
"purpose": "Provides creation, selection, and customization of system prompt presets for chat sessions.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/presets.js",
|
|
"static/js/settings.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/preset_routes.py:setup_preset_routes",
|
|
"src/preset_manager.py:PresetManager"
|
|
],
|
|
"routes": [
|
|
"/api/presets",
|
|
"/api/presets/{preset_id}"
|
|
],
|
|
"configuration": [
|
|
"PRESETS_FILE"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/presets.json"
|
|
],
|
|
"dependencies": [
|
|
"pydantic",
|
|
"json"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_preset_cli_store.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Invalid JSON syntax in user presets file can corrupt preset loading."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/preset_routes.py",
|
|
"symbol": "setup_preset_routes",
|
|
"line_range": "L30-L110",
|
|
"explanation": "API routes for listing and modifying system prompt presets."
|
|
},
|
|
{
|
|
"path": "src/preset_manager.py",
|
|
"symbol": "PresetManager",
|
|
"line_range": "L15-L100",
|
|
"explanation": "Disk-backed manager for prompt presets."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-007",
|
|
"domain": "chat",
|
|
"name": "Emoji Rendering & Twemoji SVG Proxy",
|
|
"purpose": "Proxies Twemoji SVG icons locally to render flat SVG emojis in message text without external CDN dependencies.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/emojiPicker.js",
|
|
"static/js/emojiShortcodes.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/emoji_routes.py:setup_emoji_routes"
|
|
],
|
|
"routes": [
|
|
"/api/emoji/{code}.svg"
|
|
],
|
|
"configuration": [
|
|
"EMOJI_CACHE_DIR"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/emoji_cache/"
|
|
],
|
|
"dependencies": [
|
|
"httpx",
|
|
"fastapi.responses.Response"
|
|
],
|
|
"tests": [
|
|
"tests/test_censor_pref_js.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"First request fetches SVG from remote CDN before caching locally."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/emoji_routes.py",
|
|
"symbol": "setup_emoji_routes",
|
|
"line_range": "L20-L100",
|
|
"explanation": "Serves locally cached Twemoji SVGs."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-008",
|
|
"domain": "chat",
|
|
"name": "Input History Recall (Arrow Up)",
|
|
"purpose": "Allows users to cycle through previously sent prompt messages in the chat composer input using Arrow-Up/Down keys.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/composerArrowUpRecall.js",
|
|
"static/js/chat.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"None (Pure client-side state feature)"
|
|
],
|
|
"routes": [],
|
|
"configuration": [
|
|
"localStorage key: chat_composer_history"
|
|
],
|
|
"persistence": [
|
|
"Browser localStorage"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla JavaScript DOM keyboard listeners"
|
|
],
|
|
"tests": [],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Client-side browser storage limits."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/composerArrowUpRecall.js",
|
|
"symbol": "initComposerRecall",
|
|
"line_range": "L1-L80",
|
|
"explanation": "Listens for ArrowUp keypress on composer textarea."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CHAT-009",
|
|
"domain": "chat",
|
|
"name": "Context Window Compaction & Truncation",
|
|
"purpose": "Compacts session transcript history when prompt size exceeds context limits using summarization.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chat.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/history/history_routes.py:compact_session",
|
|
"src/context_compactor.py:compact_context"
|
|
],
|
|
"routes": [
|
|
"/api/session/{session_id}/compact",
|
|
"/api/session/{session_id}/context"
|
|
],
|
|
"configuration": [
|
|
"MAX_CONTEXT_TOKENS",
|
|
"COMPACTION_THRESHOLD"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/sessions/"
|
|
],
|
|
"dependencies": [
|
|
"tiktoken",
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/test_context_compactor.py"
|
|
],
|
|
"documentation": [
|
|
"specs/architecture-runtime-inventory.md"
|
|
],
|
|
"risks": [
|
|
"Aggressive compaction may discard subtle user instructions."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/history/history_routes.py",
|
|
"symbol": "@router.post('/api/session/{session_id}/compact')",
|
|
"line_range": "L751-L790",
|
|
"explanation": "Triggers context summarization and compaction."
|
|
},
|
|
{
|
|
"path": "src/context_compactor.py",
|
|
"symbol": "compact_context",
|
|
"line_range": "L25-L110",
|
|
"explanation": "Executes context token pruning and summary generation."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-001",
|
|
"domain": "agent",
|
|
"name": "Autonomous Agent Loop & Tool Execution Engine",
|
|
"purpose": "Executes multi-step agent reasoning loops, tool invocation parsing, and automated response generation.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chatStream.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/agent_loop.py:run_agent_loop",
|
|
"src/tool_execution.py:execute_tool_call"
|
|
],
|
|
"routes": [
|
|
"/api/chat/stream"
|
|
],
|
|
"configuration": [
|
|
"MAX_AGENT_STEPS",
|
|
"ENABLE_TOOL_EXECUTION"
|
|
],
|
|
"persistence": [
|
|
"Session transcript tool calls"
|
|
],
|
|
"dependencies": [
|
|
"asyncio",
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_tool_policy.py",
|
|
"tests/test_unknown_tool_calls.py"
|
|
],
|
|
"documentation": [
|
|
"specs/architecture-runtime-inventory.md"
|
|
],
|
|
"risks": [
|
|
"Infinite tool loop if termination condition fails."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/agent_loop.py",
|
|
"symbol": "run_agent_loop",
|
|
"line_range": "L40-L210",
|
|
"explanation": "Core loop evaluating model tool requests and executing handlers."
|
|
},
|
|
{
|
|
"path": "src/tool_execution.py",
|
|
"symbol": "execute_tool_call",
|
|
"line_range": "L30-L150",
|
|
"explanation": "Dispatches tool invocation requests to underlying tool handlers."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-002",
|
|
"domain": "agent",
|
|
"name": "Scheduled Tasks & Event Bus Dispatcher",
|
|
"purpose": "Schedules background recurring or delayed tasks, emits event bus triggers, and executes automated flows.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/tasks.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/task_routes.py:setup_task_routes",
|
|
"src/task_scheduler.py:TaskScheduler",
|
|
"src/event_bus.py"
|
|
],
|
|
"routes": [
|
|
"/api/tasks",
|
|
"/api/tasks/{task_id}/run",
|
|
"/api/tasks/{task_id}/pause",
|
|
"/api/tasks/{task_id}/resume"
|
|
],
|
|
"configuration": [
|
|
"TASK_SCHEDULER_INTERVAL"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/tasks.db"
|
|
],
|
|
"dependencies": [
|
|
"apscheduler",
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_task_scheduler_cancel.py",
|
|
"tests/test_task_chain_owner_scope.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Task execution failure handling on system restart."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/task_routes.py",
|
|
"symbol": "@router.get('')",
|
|
"line_range": "L341-L370",
|
|
"explanation": "Fetches active scheduled tasks."
|
|
},
|
|
{
|
|
"path": "src/task_scheduler.py",
|
|
"symbol": "TaskScheduler",
|
|
"line_range": "L40-L280",
|
|
"explanation": "Async task scheduler dispatching cron and delay triggers."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-003",
|
|
"domain": "agent",
|
|
"name": "Webhook Event Subscriptions & Trigger Processing",
|
|
"purpose": "Manages incoming/outgoing webhook subscriptions, endpoint authentication tokens, and event triggers.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/admin.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/webhook_routes.py:setup_webhook_routes",
|
|
"src/webhook_manager.py:WebhookManager"
|
|
],
|
|
"routes": [
|
|
"/api/webhooks",
|
|
"/v1/chat",
|
|
"/api/webhooks/{webhook_id}/test"
|
|
],
|
|
"configuration": [
|
|
"WEBHOOK_SECRET_KEY"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/webhooks.db"
|
|
],
|
|
"dependencies": [
|
|
"httpx",
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_webhook_ssrf_resilience.py",
|
|
"tests/test_webhook_trigger_auth_exempt.py"
|
|
],
|
|
"documentation": [
|
|
"docs/pr-blocker-audit.md"
|
|
],
|
|
"risks": [
|
|
"SSRF risks when contacting external webhook URLs if unvalidated."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/webhook_routes.py",
|
|
"symbol": "@router.get('/webhooks')",
|
|
"line_range": "L71-L94",
|
|
"explanation": "Returns list of registered webhooks."
|
|
},
|
|
{
|
|
"path": "src/webhook_manager.py",
|
|
"symbol": "WebhookManager",
|
|
"line_range": "L30-L160",
|
|
"explanation": "Handles payload delivery and signature verification."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-004",
|
|
"domain": "agent",
|
|
"name": "Assistant Settings, Task Check-Ins & Background Job Monitor",
|
|
"purpose": "Manages per-user assistant sessions and scheduled check-in settings, drains background job completions, and retains a legacy no-op activity logging shim.",
|
|
"status": "partial",
|
|
"frontend_entrypoints": [
|
|
"static/js/assistant.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/assistant_routes.py:setup_assistant_routes",
|
|
"src/assistant_log.py",
|
|
"src/bg_monitor.py"
|
|
],
|
|
"routes": [
|
|
"/api/assistant/session",
|
|
"/api/assistant/settings",
|
|
"/api/assistant/run/{task_id}",
|
|
"/api/assistant/run-status/{task_id}",
|
|
"/api/assistant/available-timezones"
|
|
],
|
|
"configuration": [
|
|
"CrewMember.timezone (IANA tz name driving check-in scheduling)",
|
|
"CrewMember.model",
|
|
"CrewMember.enabled_tools",
|
|
"ScheduledTask.scheduled_time / ScheduledTask.status",
|
|
"src/bg_monitor.py:POLL_INTERVAL_S",
|
|
"src/bg_monitor.py:_FOLLOWUP_MAX_ROUNDS"
|
|
],
|
|
"persistence": [
|
|
"CrewMember (core/database.py, is_default_assistant singleton per owner)",
|
|
"Session pinned via CrewMember.session_id",
|
|
"ScheduledTask (per-owner check-in rows)",
|
|
"TaskRun (most recent run status for run-status polling)"
|
|
],
|
|
"dependencies": [
|
|
"logging",
|
|
"asyncio"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_logs_cli_resolve_nonstring.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Assistant seeding is owner-scoped: routes/assistant_routes.py documents that reaching an /api/assistant route under a synthetic owner previously seeded a duplicate CrewMember plus Morning/Midday/Evening tasks that double-fired; correctness now depends on RESERVED_USERNAMES staying complete.",
|
|
"Check-in next_run values are recomputed from CrewMember.timezone through compute_next_run, so a missing or stale IANA timezone shifts when check-ins fire.",
|
|
"Background follow-up continuation is retry-until-success: _run_followup returns False to defer and mark_followed_up() runs only after a successful agent run, so a persistently failing continuation is retried every POLL_INTERVAL_S tick without a bounded attempt count."
|
|
],
|
|
"unknowns": [
|
|
"Route `/api/assistant/logs` cited in legacy docs is absent from assistant router.",
|
|
"Existing unit test `tests/cli/test_logs_cli_resolve_nonstring.py` tests CLI target-name resolution logic, not active assistant routes or bg_monitor execution loop."
|
|
],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/assistant_routes.py",
|
|
"symbol": "setup_assistant_routes",
|
|
"line_range": "L80-L326",
|
|
"explanation": "Active assistant session, settings, manual check-in, run-status and timezone-list endpoints, including the owner-scoping guards."
|
|
},
|
|
{
|
|
"path": "src/bg_monitor.py",
|
|
"symbol": "_drain_agent",
|
|
"line_range": "L28-L72",
|
|
"explanation": "Runs the agent loop headless against a session to produce the background-job follow-up turn."
|
|
},
|
|
{
|
|
"path": "src/bg_monitor.py",
|
|
"symbol": "_run_followup",
|
|
"line_range": "L75-L132",
|
|
"explanation": "Drains completed background jobs and auto-continues the owning session, deferring while a live turn is in progress."
|
|
},
|
|
{
|
|
"path": "src/assistant_log.py",
|
|
"symbol": "log_to_assistant",
|
|
"line_range": "L34-L48",
|
|
"explanation": "Legacy no-op activity logging shim retained for existing callers; documented as inactive rather than as current behaviour."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-005",
|
|
"domain": "agent",
|
|
"name": "Model Context Protocol (MCP) Server Integration",
|
|
"purpose": "Integrates external MCP servers over stdio/SSE to expand agent capabilities dynamically.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/settings.js",
|
|
"static/js/admin.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/mcp_routes.py:setup_mcp_routes",
|
|
"src/mcp_manager.py:McpManager",
|
|
"mcp_servers/"
|
|
],
|
|
"routes": [
|
|
"/api/mcp/servers",
|
|
"/api/mcp/tools",
|
|
"/api/mcp/connect"
|
|
],
|
|
"configuration": [
|
|
"MCP_CONFIG_PATH"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/mcp_config.json"
|
|
],
|
|
"dependencies": [
|
|
"mcp",
|
|
"asyncio"
|
|
],
|
|
"tests": [
|
|
"tests/test_mcp_param_hint_hardening.py",
|
|
"tests/cli/test_mcp_cli_json.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Subprocess leaks if external MCP server process fails to terminate clean."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/mcp_routes.py",
|
|
"symbol": "setup_mcp_routes",
|
|
"line_range": "L60-L240",
|
|
"explanation": "Exposes management endpoints for external MCP servers."
|
|
},
|
|
{
|
|
"path": "src/mcp_manager.py",
|
|
"symbol": "McpManager",
|
|
"line_range": "L40-L300",
|
|
"explanation": "Manages MCP server subprocess lifecycles."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-006",
|
|
"domain": "agent",
|
|
"name": "AI Interaction Tools & Pipeline Orchestration",
|
|
"purpose": "Provides specialized AI interaction tools for agent self-debugging, debate, and multi-model collaboration.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chatStream.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/ai_interaction.py",
|
|
"src/action_intents.py",
|
|
"src/builtin_actions.py"
|
|
],
|
|
"routes": [
|
|
"Implicit agent tool calls"
|
|
],
|
|
"configuration": [
|
|
"MAX_PIPELINE_TURNS"
|
|
],
|
|
"persistence": [
|
|
"Session transcript state"
|
|
],
|
|
"dependencies": [
|
|
"asyncio"
|
|
],
|
|
"tests": [
|
|
"tests/test_builtin_actions_nonstring.py",
|
|
"tests/test_model_interaction_registry.py"
|
|
],
|
|
"documentation": [
|
|
"specs/architecture-runtime-inventory.md"
|
|
],
|
|
"risks": [
|
|
"High API token consumption during extended agent debates."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/ai_interaction.py",
|
|
"symbol": "init_ai_interaction_tools",
|
|
"line_range": "L30-L140",
|
|
"explanation": "Registers specialized multi-agent interaction primitives."
|
|
},
|
|
{
|
|
"path": "src/builtin_actions.py",
|
|
"symbol": "execute_builtin_action",
|
|
"line_range": "L20-L90",
|
|
"explanation": "Executes pre-built action intent sequences."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "AGENT-007",
|
|
"domain": "agent",
|
|
"name": "Subprocess & Background Job Execution Tools",
|
|
"purpose": "Provides sandboxed bash/shell tool execution capabilities with output streaming and background tracking.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chatStream.js",
|
|
"static/js/tasks.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/agent_tools/subprocess_tools.py",
|
|
"src/agent_tools/bg_job_tools.py",
|
|
"src/bg_jobs.py"
|
|
],
|
|
"routes": [
|
|
"Implicit agent tool calls"
|
|
],
|
|
"configuration": [
|
|
"ALLOW_SHELL_EXECUTION",
|
|
"SANDBOX_DIR"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/bg_jobs/"
|
|
],
|
|
"dependencies": [
|
|
"subprocess",
|
|
"asyncio"
|
|
],
|
|
"tests": [
|
|
"tests/test_bg_job_tools.py",
|
|
"tests/test_task_shell_tools.py"
|
|
],
|
|
"documentation": [
|
|
"THREAT_MODEL.md"
|
|
],
|
|
"risks": [
|
|
"Arbitrary shell command execution permissions if sandbox confinement fails."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/agent_tools/subprocess_tools.py",
|
|
"symbol": "run_command",
|
|
"line_range": "L25-L120",
|
|
"explanation": "Executes shell commands in background/foreground."
|
|
},
|
|
{
|
|
"path": "src/bg_jobs.py",
|
|
"symbol": "JobManager",
|
|
"line_range": "L30-L150",
|
|
"explanation": "Tracks async background subprocess tasks."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-001",
|
|
"domain": "model",
|
|
"name": "Multi-Provider LLM Model Discovery & Metadata Management",
|
|
"purpose": "Discovers models from OpenAI, Anthropic, Ollama, vLLM, LMStudio, OpenRouter, and Google AI Studio endpoints.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/models.js",
|
|
"static/js/modelPicker.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/model_routes.py:setup_model_routes",
|
|
"src/model_discovery.py:ModelDiscovery"
|
|
],
|
|
"routes": [
|
|
"/api/models",
|
|
"/api/models/active",
|
|
"/api/model-endpoints"
|
|
],
|
|
"configuration": [
|
|
"OPENAI_API_KEY",
|
|
"OLLAMA_BASE_URL",
|
|
"ANTHROPIC_API_KEY"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/model_endpoints.json"
|
|
],
|
|
"dependencies": [
|
|
"httpx",
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_model_routes.py",
|
|
"tests/test_provider_classification.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Remote endpoint timeouts may slow down full discovery refresh."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/model_routes.py",
|
|
"symbol": "@router.get('/api/models')",
|
|
"line_range": "L100-L180",
|
|
"explanation": "Returns unified list of available models across providers."
|
|
},
|
|
{
|
|
"path": "src/model_discovery.py",
|
|
"symbol": "ModelDiscovery.discover_all",
|
|
"line_range": "L45-L210",
|
|
"explanation": "Queries connected provider endpoints for available model IDs."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-002",
|
|
"domain": "model",
|
|
"name": "Model Capability & Context Limits Detection",
|
|
"purpose": "Detects vision, tool calling, reasoning, and context window limits for connected model endpoints.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/models.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/model_capabilities.py",
|
|
"src/model_context.py",
|
|
"src/endpoint_resolver.py"
|
|
],
|
|
"routes": [
|
|
"/api/model-endpoints/{ep_id}/probe"
|
|
],
|
|
"configuration": [
|
|
"MODEL_CAPABILITY_OVERRODES"
|
|
],
|
|
"persistence": [
|
|
"In-memory capabilities cache"
|
|
],
|
|
"dependencies": [
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_endpoint_resolver_headers.py",
|
|
"tests/test_vision_model_detection.py"
|
|
],
|
|
"documentation": [
|
|
"specs/architecture-runtime-inventory.md"
|
|
],
|
|
"risks": [
|
|
"Incorrect context limit metadata for unlisted custom fine-tunes."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/model_capabilities.py",
|
|
"symbol": "get_model_capabilities",
|
|
"line_range": "L30-L120",
|
|
"explanation": "Maps model names to vision and tool support flags."
|
|
},
|
|
{
|
|
"path": "src/endpoint_resolver.py",
|
|
"symbol": "resolve_endpoint_headers",
|
|
"line_range": "L20-L80",
|
|
"explanation": "Resolves auth headers and target URLs for model endpoints."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-003",
|
|
"domain": "model",
|
|
"name": "LLM Core Provider Communication & Fallback Routing",
|
|
"purpose": "Manages HTTP request dispatching, authorization header injection, and fallback provider routing for LLM calls.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chatStream.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/llm_core.py:llm_call_async",
|
|
"src/llm_core.py:llm_call_async_with_fallback",
|
|
"src/llm_core.py:stream_llm_with_fallback"
|
|
],
|
|
"routes": [
|
|
"Implicit backend calls"
|
|
],
|
|
"configuration": [
|
|
"LLM_RETRY_ATTEMPTS",
|
|
"LLM_TIMEOUT"
|
|
],
|
|
"persistence": [
|
|
"Session state"
|
|
],
|
|
"dependencies": [
|
|
"httpx",
|
|
"asyncio"
|
|
],
|
|
"tests": [
|
|
"tests/test_llm_core_concurrency.py",
|
|
"tests/test_llm_core_fallback.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Unexpected API changes in upstream third-party model providers."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/llm_core.py",
|
|
"symbol": "llm_call_async",
|
|
"line_range": "L1949-L2118",
|
|
"explanation": "Non-streaming provider request dispatcher: resolves the endpoint, injects authorization headers and executes the HTTP call."
|
|
},
|
|
{
|
|
"path": "src/llm_core.py",
|
|
"symbol": "llm_call_async_with_fallback",
|
|
"line_range": "L1932-L1946",
|
|
"explanation": "Ordered fallback wrapper that retries llm_call_async across the configured candidate endpoints."
|
|
},
|
|
{
|
|
"path": "src/llm_core.py",
|
|
"symbol": "stream_llm_with_fallback",
|
|
"line_range": "L2794-L2895",
|
|
"explanation": "Ordered fallback wrapper for the streaming path; advances to the next candidate when a provider yields an empty completion."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Provider dispatch, header injection and fallback advancement are only observable against a reachable LLM provider endpoint; not exercised in this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-004",
|
|
"domain": "model",
|
|
"name": "Model Selection & Display Ordering Preferences",
|
|
"purpose": "Allows pinning, sorting, and hiding specific models in the UI selection dropdown.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/modelSort.js",
|
|
"static/js/modelPicker.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/model_routes.py:save_model_order"
|
|
],
|
|
"routes": [
|
|
"/api/models/order",
|
|
"/api/models/order/reset"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/model_order.json"
|
|
],
|
|
"dependencies": [
|
|
"json"
|
|
],
|
|
"tests": [
|
|
"tests/test_model_defaults.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Stale model IDs in custom order lists after model endpoints are removed."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/model_routes.py",
|
|
"symbol": "@router.post('/order')",
|
|
"line_range": "L500-L550",
|
|
"explanation": "Saves custom model display order preference."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-005",
|
|
"domain": "model",
|
|
"name": "Side-by-Side Model Comparison (A/B Testing)",
|
|
"purpose": "Enables dual-model side-by-side response evaluation, arena scoring, and latency comparison.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/compare/index.js",
|
|
"static/js/compare/panes.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/compare/compare_routes.py:setup_compare_routes"
|
|
],
|
|
"routes": [
|
|
"/api/compare/start",
|
|
"/api/compare/{comp_id}/vote",
|
|
"/api/compare/history"
|
|
],
|
|
"configuration": [
|
|
"COMPARE_ENABLED"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/compare_history.db"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_endpoint_owner_scope_followup.py"
|
|
],
|
|
"documentation": [
|
|
"docs/compare.webm"
|
|
],
|
|
"risks": [
|
|
"High memory and network usage when streaming two model responses simultaneously."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/compare/compare_routes.py",
|
|
"symbol": "@router.post('/start')",
|
|
"line_range": "L70-L150",
|
|
"explanation": "Starts a parallel dual-model comparison stream."
|
|
},
|
|
{
|
|
"path": "static/js/compare/index.js",
|
|
"symbol": "initCompareView",
|
|
"line_range": "L1-L100",
|
|
"explanation": "Renders side-by-side model chat panes."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-006",
|
|
"domain": "model",
|
|
"name": "GitHub Copilot Device Flow Authentication",
|
|
"purpose": "Authenticates with GitHub Copilot via OAuth device flow to use Copilot models directly.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/providerDeviceFlow.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/copilot_routes.py:setup_copilot_routes",
|
|
"routes/device_flow.py:create_device_flow_router",
|
|
"src/copilot.py:request_device_code",
|
|
"src/copilot.py:poll_access_token"
|
|
],
|
|
"routes": [
|
|
"/api/copilot/device/start",
|
|
"/api/copilot/device/poll"
|
|
],
|
|
"configuration": [
|
|
"COPILOT_CLIENT_ID"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/copilot_auth.json"
|
|
],
|
|
"dependencies": [
|
|
"httpx"
|
|
],
|
|
"tests": [
|
|
"tests/test_provider_device_flow_js.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Token expiration requires manual device re-authentication."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/copilot_routes.py",
|
|
"symbol": "setup_copilot_routes",
|
|
"line_range": "L166-L173",
|
|
"explanation": "Builds the Copilot device-flow router at prefix /api/copilot, wiring _start_device_flow and _poll_device_flow."
|
|
},
|
|
{
|
|
"path": "routes/device_flow.py",
|
|
"symbol": "create_device_flow_router",
|
|
"line_range": "L135-L193",
|
|
"explanation": "Shared factory registering POST /device/start and POST /device/poll under the caller-supplied prefix."
|
|
},
|
|
{
|
|
"path": "src/copilot.py",
|
|
"symbol": "request_device_code",
|
|
"line_range": "L150-L161",
|
|
"explanation": "Issues the GitHub device-code request that begins the Copilot OAuth device flow."
|
|
},
|
|
{
|
|
"path": "src/copilot.py",
|
|
"symbol": "poll_access_token",
|
|
"line_range": "L164-L180",
|
|
"explanation": "Polls GitHub for the access token once the user has authorized the device code."
|
|
},
|
|
{
|
|
"path": "tests/test_provider_device_flow_js.py",
|
|
"symbol": "test_copilot_success_uses_complete_verification_uri",
|
|
"line_range": "L28-L65",
|
|
"explanation": "Inspected unit test asserting the Copilot device-flow runner surfaces the complete verification URI returned by the backend."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E2",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires an interactive GitHub Copilot OAuth device-flow account."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-007",
|
|
"domain": "model",
|
|
"name": "ChatGPT Subscription Device Flow Authentication",
|
|
"purpose": "Authenticates with ChatGPT Pro/Plus subscription tokens via device login flow.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/providerDeviceFlow.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/chatgpt_subscription_routes.py:setup_chatgpt_subscription_routes",
|
|
"routes/device_flow.py:create_device_flow_router",
|
|
"src/chatgpt_subscription.py:request_device_code",
|
|
"src/chatgpt_subscription.py:poll_device_auth"
|
|
],
|
|
"routes": [
|
|
"/api/chatgpt-subscription/device/start",
|
|
"/api/chatgpt-subscription/device/poll"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/chatgpt_auth.json"
|
|
],
|
|
"dependencies": [
|
|
"httpx"
|
|
],
|
|
"tests": [
|
|
"tests/test_provider_device_flow_js.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Changes in OpenAI auth endpoint security challenges."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/chatgpt_subscription_routes.py",
|
|
"symbol": "setup_chatgpt_subscription_routes",
|
|
"line_range": "L163-L170",
|
|
"explanation": "Builds the ChatGPT subscription device-flow router at prefix /api/chatgpt-subscription."
|
|
},
|
|
{
|
|
"path": "routes/device_flow.py",
|
|
"symbol": "create_device_flow_router",
|
|
"line_range": "L135-L193",
|
|
"explanation": "Shared factory registering POST /device/start and POST /device/poll under the caller-supplied prefix."
|
|
},
|
|
{
|
|
"path": "src/chatgpt_subscription.py",
|
|
"symbol": "request_device_code",
|
|
"line_range": "L168-L181",
|
|
"explanation": "Issues the ChatGPT device-authorization request that begins the subscription OAuth device flow."
|
|
},
|
|
{
|
|
"path": "src/chatgpt_subscription.py",
|
|
"symbol": "poll_device_auth",
|
|
"line_range": "L184-L193",
|
|
"explanation": "Polls the ChatGPT device-authorization endpoint for completion using the stored device_auth_id and user_code."
|
|
},
|
|
{
|
|
"path": "tests/test_provider_device_flow_js.py",
|
|
"symbol": "test_chatgpt_success_uses_plain_verification_uri",
|
|
"line_range": "L68-L95",
|
|
"explanation": "Inspected unit test asserting the ChatGPT device-flow runner uses the plain verification URI rather than the Copilot complete-URI form."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E2",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires an interactive ChatGPT subscription OAuth flow."
|
|
}
|
|
},
|
|
{
|
|
"id": "MODEL-008",
|
|
"domain": "model",
|
|
"name": "Embedding Model Lane & Vector Provider Setup",
|
|
"purpose": "Configures local sentence-transformers, FastEmbed, or remote OpenAI embedding model lanes.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/settings.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/embedding_routes.py:setup_embedding_routes",
|
|
"src/embeddings.py",
|
|
"src/embedding_lanes.py"
|
|
],
|
|
"routes": [
|
|
"/api/embeddings/active",
|
|
"/api/embeddings/test"
|
|
],
|
|
"configuration": [
|
|
"EMBEDDING_PROVIDER",
|
|
"EMBEDDING_MODEL"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/embeddings_config.json"
|
|
],
|
|
"dependencies": [
|
|
"fastembed",
|
|
"sentence-transformers"
|
|
],
|
|
"tests": [
|
|
"tests/test_embedding_lane_ndarray_restore.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"First-time download of heavy PyTorch model weights on CPU-only machines."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/embedding_routes.py",
|
|
"symbol": "setup_embedding_routes",
|
|
"line_range": "L30-L120",
|
|
"explanation": "Provides embedding provider configuration endpoints."
|
|
},
|
|
{
|
|
"path": "src/embeddings.py",
|
|
"symbol": "EmbeddingManager",
|
|
"line_range": "L40-L200",
|
|
"explanation": "Generates dense vector embeddings for RAG and memory."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "COOKBOOK-001",
|
|
"domain": "cookbook",
|
|
"name": "Local Model Download & Recipe Lifecycle Management",
|
|
"purpose": "Downloads HuggingFace models, configures execution parameters, and manages local GGUF/MLX model servers.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/cookbook.js",
|
|
"static/js/cookbookServe.js",
|
|
"static/js/cookbookDownload.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/cookbook_routes.py:setup_cookbook_routes",
|
|
"src/tools/cookbook.py",
|
|
"src/cookbook_serve_lifecycle.py"
|
|
],
|
|
"routes": [
|
|
"/api/cookbook/download",
|
|
"/api/cookbook/serve",
|
|
"/api/cookbook/status"
|
|
],
|
|
"configuration": [
|
|
"COOKBOOK_MODELS_DIR"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/models/"
|
|
],
|
|
"dependencies": [
|
|
"huggingface_hub",
|
|
"subprocess"
|
|
],
|
|
"tests": [
|
|
"tests/test_cookbook_endpoint_registration.py",
|
|
"tests/test_cookbook_port_parsing_js.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Disk space exhaustion during multi-gigabyte GGUF weights downloads."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/cookbook_routes.py",
|
|
"symbol": "setup_cookbook_routes",
|
|
"line_range": "L100-L300",
|
|
"explanation": "Exposes model downloading and process serving endpoints."
|
|
},
|
|
{
|
|
"path": "static/js/cookbook.js",
|
|
"symbol": "initCookbook",
|
|
"line_range": "L1-L150",
|
|
"explanation": "UI manager for local model library."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "COOKBOOK-002",
|
|
"domain": "cookbook",
|
|
"name": "Hardware Model Fitting ('What Fits?') Analysis Engine",
|
|
"purpose": "Calculates RAM/VRAM requirements, quantized size, and context overhead to determine model compatibility.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/cookbook-hwfit.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/hwfit_routes.py:setup_hwfit_routes",
|
|
"services/hwfit/fit.py:calculate_fit"
|
|
],
|
|
"routes": [
|
|
"/api/hwfit/fit",
|
|
"/api/hwfit/profile"
|
|
],
|
|
"configuration": [
|
|
"FORCE_GPU_VENDOR"
|
|
],
|
|
"persistence": [
|
|
"System hardware specs"
|
|
],
|
|
"dependencies": [
|
|
"psutil",
|
|
"torch"
|
|
],
|
|
"tests": [
|
|
"tests/test_hwfit_gemma4_12b.py",
|
|
"tests/test_hwfit_bandwidth_nonstring.py",
|
|
"tests/test_hwfit_gpu_count_nonnumeric.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Inaccurate VRAM estimation for non-standard KV-cache quantization."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/hwfit_routes.py",
|
|
"symbol": "setup_hwfit_routes",
|
|
"line_range": "L40-L120",
|
|
"explanation": "Calculates hardware model compatibility."
|
|
},
|
|
{
|
|
"path": "services/hwfit/fit.py",
|
|
"symbol": "calculate_fit",
|
|
"line_range": "L30-L140",
|
|
"explanation": "Performs parameter and memory fit calculations."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "COOKBOOK-003",
|
|
"domain": "cookbook",
|
|
"name": "HuggingFace & MLX Model Discovery Services",
|
|
"purpose": "Searches HuggingFace Hub and local MLX model repositories for compatible GGUF and MLX weights.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/cookbook.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/hwfit_routes.py:hf_search",
|
|
"services/hwfit/hf_discovery.py"
|
|
],
|
|
"routes": [
|
|
"/api/hwfit/hf-search",
|
|
"/api/hwfit/mlx-models"
|
|
],
|
|
"configuration": [
|
|
"HF_TOKEN"
|
|
],
|
|
"persistence": [
|
|
"Cache directory"
|
|
],
|
|
"dependencies": [
|
|
"huggingface_hub"
|
|
],
|
|
"tests": [
|
|
"tests/test_cookbook_hf_token.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"HuggingFace API rate limits when searching without an API token."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "services/hwfit/hf_discovery.py",
|
|
"symbol": "search_hf_models",
|
|
"line_range": "L20-L90",
|
|
"explanation": "Queries HuggingFace API for model tags and files."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "COOKBOOK-004",
|
|
"domain": "cookbook",
|
|
"name": "Host Docker Access for Inference Container Runtimes",
|
|
"purpose": "Detects and connects to host Docker engine to launch containerized Ollama, vLLM, or SGLang runtimes.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/cookbookServe.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/host_docker_access.py:HostDockerAccess"
|
|
],
|
|
"routes": [
|
|
"Implicit local docker socket API calls"
|
|
],
|
|
"configuration": [
|
|
"DOCKER_HOST"
|
|
],
|
|
"persistence": [
|
|
"/var/run/docker.sock"
|
|
],
|
|
"dependencies": [
|
|
"docker"
|
|
],
|
|
"tests": [
|
|
"tests/test_cookbook_docker_access.py"
|
|
],
|
|
"documentation": [
|
|
"docker/host-docker.yml"
|
|
],
|
|
"risks": [
|
|
"Permission denied accessing docker socket on non-root setups."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/host_docker_access.py",
|
|
"symbol": "HostDockerAccess",
|
|
"line_range": "L50-L62",
|
|
"explanation": "Interacts with host docker daemon."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires Docker access and supported physical GPU hardware."
|
|
}
|
|
},
|
|
{
|
|
"id": "RESEARCH-001",
|
|
"domain": "research",
|
|
"name": "Deep Research Execution Engine & SSE Progress Streaming",
|
|
"purpose": "Executes multi-step recursive deep research tasks, web page scraping, synthesis, and streams live progress.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/research/panel.js",
|
|
"static/js/research/jobs.js",
|
|
"static/js/researchSynapse.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/research/research_routes.py:start_research",
|
|
"src/deep_research.py",
|
|
"services/research/service.py"
|
|
],
|
|
"routes": [
|
|
"/api/research/start",
|
|
"/api/research/stream/{session_id}",
|
|
"/api/research/active"
|
|
],
|
|
"configuration": [
|
|
"MAX_RESEARCH_DEPTH",
|
|
"SEARXNG_URL"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/research/"
|
|
],
|
|
"dependencies": [
|
|
"beautifulsoup4",
|
|
"httpx",
|
|
"asyncio"
|
|
],
|
|
"tests": [
|
|
"tests/test_research_owner_scope_routes.py",
|
|
"tests/test_services_research_low_quality_sources.py"
|
|
],
|
|
"documentation": [
|
|
"docs/research.webm"
|
|
],
|
|
"risks": [
|
|
"High memory consumption when parsing multi-megabyte HTML target pages."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/research/research_routes.py",
|
|
"symbol": "@router.post('/api/research/start')",
|
|
"line_range": "L492-L550",
|
|
"explanation": "Initiates deep research job."
|
|
},
|
|
{
|
|
"path": "src/deep_research.py",
|
|
"symbol": "DeepResearchEngine",
|
|
"line_range": "L40-L300",
|
|
"explanation": "Recursive search and summary crawler."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "RESEARCH-002",
|
|
"domain": "research",
|
|
"name": "Research Library, Detail View & Image Controls",
|
|
"purpose": "Stores completed research reports, generated diagrams, reference links, and manages image visibility.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/research/panel.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/research/research_routes.py:get_library"
|
|
],
|
|
"routes": [
|
|
"/api/research/library",
|
|
"/api/research/detail/{session_id}",
|
|
"/api/research/{session_id}/hide-image"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/research/library.json"
|
|
],
|
|
"dependencies": [
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_research_cli_preview.py",
|
|
"tests/test_research_routes_path_confinement.py"
|
|
],
|
|
"documentation": [
|
|
"docs/research.webm"
|
|
],
|
|
"risks": [
|
|
"Orphaned report files if storage directory is modified out-of-band."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/research/research_routes.py",
|
|
"symbol": "@router.get('/api/research/library')",
|
|
"line_range": "L366-L415",
|
|
"explanation": "Returns all saved research reports."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "RESEARCH-003",
|
|
"domain": "research",
|
|
"name": "Web Search Engine Integration (SearXNG & Multi-Provider)",
|
|
"purpose": "Queries SearXNG, DuckDuckGo, or Google Search instances to retrieve web search snippets.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chat.js",
|
|
"static/js/search.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/search_routes.py:setup_search_routes",
|
|
"src/search/core.py",
|
|
"services/search/service.py"
|
|
],
|
|
"routes": [
|
|
"/api/search"
|
|
],
|
|
"configuration": [
|
|
"SEARXNG_URL",
|
|
"SEARCH_PROVIDER"
|
|
],
|
|
"persistence": [
|
|
"In-memory search cache"
|
|
],
|
|
"dependencies": [
|
|
"httpx"
|
|
],
|
|
"tests": [
|
|
"tests/test_search_ranking.py",
|
|
"tests/test_searxng_image_pinned.py"
|
|
],
|
|
"documentation": [
|
|
"config/searxng/settings.yml"
|
|
],
|
|
"risks": [
|
|
"Search provider IP throttling or rate-limiting."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/search_routes.py",
|
|
"symbol": "setup_search_routes",
|
|
"line_range": "L39-L100",
|
|
"explanation": "Defines /api/search, /api/search/config, and /api/search/query endpoints."
|
|
},
|
|
{
|
|
"path": "src/search/core.py",
|
|
"symbol": "SearchEngine",
|
|
"line_range": "L1-L12",
|
|
"explanation": "Compatibility module aliasing services.search.core."
|
|
},
|
|
{
|
|
"path": "tests/test_search_ranking.py",
|
|
"symbol": "test_news_queries_prefer_news_sources_over_sports_and_social_results",
|
|
"line_range": "L1-L39",
|
|
"explanation": "Tests search result domain ranking and scoring."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires an active SearXNG instance or external search API provider."
|
|
}
|
|
},
|
|
{
|
|
"id": "RESEARCH-004",
|
|
"domain": "research",
|
|
"name": "Research Result Peeking & Topic Spinoff Generation",
|
|
"purpose": "Extracts preliminary research snippets and spawns child research sessions focused on specific sub-topics.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/research/panel.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/research/research_routes.py:peek_result",
|
|
"routes/research/research_routes.py:spinoff_research"
|
|
],
|
|
"routes": [
|
|
"/api/research/result-peek/{session_id}",
|
|
"/api/research/spinoff/{session_id}"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/research/"
|
|
],
|
|
"dependencies": [
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/test_research_routes_path_confinement.py"
|
|
],
|
|
"documentation": [
|
|
"docs/research.webm"
|
|
],
|
|
"risks": [
|
|
"Deep recursion tree depth when spawning multiple nested spinoffs."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/research/research_routes.py",
|
|
"symbol": "@router.post('/api/research/spinoff/{session_id}')",
|
|
"line_range": "L635-L680",
|
|
"explanation": "Spawns child research session for specific query."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "DOCUMENT-001",
|
|
"domain": "document",
|
|
"name": "Document & Canvas Artifact Management",
|
|
"purpose": "Renders dynamic canvas documents, handles live editing, markdown preview, and side-by-side artifact display.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/document.js",
|
|
"static/js/documentLibrary.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/document_routes.py:setup_document_routes",
|
|
"src/document_actions.py",
|
|
"src/document_processor.py"
|
|
],
|
|
"routes": [
|
|
"/api/document",
|
|
"/api/document/{id}"
|
|
],
|
|
"configuration": [
|
|
"MAX_DOCUMENT_SIZE_MB"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/documents/"
|
|
],
|
|
"dependencies": [
|
|
"pydantic",
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/test_document_actions_nonstring.py",
|
|
"tests/test_document_diff_discard_on_update_js.py"
|
|
],
|
|
"documentation": [
|
|
"docs/document.webm"
|
|
],
|
|
"risks": [
|
|
"Concurrent edits on the same document artifact."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/document_routes.py",
|
|
"symbol": "setup_document_routes",
|
|
"line_range": "L100-L300",
|
|
"explanation": "Registers document artifact CRUD routes."
|
|
},
|
|
{
|
|
"path": "static/js/document.js",
|
|
"symbol": "initDocumentView",
|
|
"line_range": "L1-L150",
|
|
"explanation": "Renders interactive canvas document panel."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "DOCUMENT-002",
|
|
"domain": "document",
|
|
"name": "PDF Form Processing & High-Fidelity Rendering",
|
|
"purpose": "Extracts form fields from PDF files, fills dynamic values, and generates PDF previews.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/document.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/pdf_runtime.py",
|
|
"src/pdf_forms.py",
|
|
"src/pdf_form_doc.py"
|
|
],
|
|
"routes": [
|
|
"Implicit PDF document processing"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/documents/pdf/"
|
|
],
|
|
"dependencies": [
|
|
"pypdf",
|
|
"fitz"
|
|
],
|
|
"tests": [
|
|
"tests/test_document_pdf_marker.py",
|
|
"tests/test_security_headers_pdf_preview.py"
|
|
],
|
|
"documentation": [
|
|
"docs/attachments.md"
|
|
],
|
|
"risks": [
|
|
"Complex XFA PDF forms may not extract cleanly with standard pdf parsers."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/pdf_runtime.py",
|
|
"symbol": "load_pymupdf_for_pdf_viewer",
|
|
"line_range": "L9-L15",
|
|
"explanation": "Loads optional PyMuPDF runtime for PDF viewing."
|
|
},
|
|
{
|
|
"path": "src/pdf_forms.py",
|
|
"symbol": "extract_form_fields",
|
|
"line_range": "L1-L100",
|
|
"explanation": "Handles PDF form field extraction and filling."
|
|
},
|
|
{
|
|
"path": "tests/test_document_pdf_marker.py",
|
|
"symbol": "test_marker_removed_without_eating_following_text",
|
|
"line_range": "L1-L30",
|
|
"explanation": "Tests PDF text extraction wrapper stripping without content corruption."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires optional PyMuPDF (`fitz`) or pypdf runtime dependency."
|
|
}
|
|
},
|
|
{
|
|
"id": "DOCUMENT-003",
|
|
"domain": "document",
|
|
"name": "Personal Document Indexing & RAG Retrieval",
|
|
"purpose": "Indexes local user documents (PDF, DOCX, TXT) into ChromaDB for semantic vector retrieval.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/rag.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/personal_routes.py:setup_personal_routes",
|
|
"src/personal_docs.py",
|
|
"src/rag_manager.py"
|
|
],
|
|
"routes": [
|
|
"/api/personal/documents",
|
|
"/api/personal/search",
|
|
"/api/personal/index"
|
|
],
|
|
"configuration": [
|
|
"CHROMADB_DIR"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/chroma/"
|
|
],
|
|
"dependencies": [
|
|
"chromadb",
|
|
"pypdf",
|
|
"docx"
|
|
],
|
|
"tests": [
|
|
"tests/test_personal_docs_pdf_index.py",
|
|
"tests/test_rag_index_hidden_dirs.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Slow vector embedding indexing step for massive multi-thousand page documents."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/personal_routes.py",
|
|
"symbol": "setup_personal_routes",
|
|
"line_range": "L50-L160",
|
|
"explanation": "Personal document RAG indexing and search API endpoints."
|
|
},
|
|
{
|
|
"path": "src/personal_docs.py",
|
|
"symbol": "PersonalDocsManager",
|
|
"line_range": "L30-L180",
|
|
"explanation": "Handles file text chunking and vector storage."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "DOCUMENT-004",
|
|
"domain": "document",
|
|
"name": "Document Conversion & Text Extraction Engine",
|
|
"purpose": "Converts office formats (.docx, .xlsx, .pptx) and HTML into clean Markdown text representations.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/fileHandler.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/markitdown_runtime.py",
|
|
"src/office_doc.py"
|
|
],
|
|
"routes": [
|
|
"Implicit file conversion calls"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"Temporary conversion cache"
|
|
],
|
|
"dependencies": [
|
|
"markitdown",
|
|
"python-docx"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_docs_cli_content_length.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Formatting loss when parsing legacy binary doc/xls files."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/markitdown_runtime.py",
|
|
"symbol": "convert_to_markdown",
|
|
"line_range": "L15-L80",
|
|
"explanation": "Converts binary office documents into structured Markdown text."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "DOCUMENT-005",
|
|
"domain": "document",
|
|
"name": "Document Library UI Navigation",
|
|
"purpose": "Provides dedicated UI view for browsing, filtering, and organizing saved user documents.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/documentLibrary.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"app.py:serve_library"
|
|
],
|
|
"routes": [
|
|
"/library"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/documents/"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla JS"
|
|
],
|
|
"tests": [
|
|
"tests/test_document_close_clears_active_route.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Large folder trees may cause initial DOM render slowdown."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/documentLibrary.js",
|
|
"symbol": "initDocumentLibrary",
|
|
"line_range": "L1-L100",
|
|
"explanation": "Renders document library navigation grid."
|
|
},
|
|
{
|
|
"path": "app.py",
|
|
"symbol": "serve_library",
|
|
"line_range": "L911-L914",
|
|
"explanation": "Serves SPA shell for /library route."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "EMAIL-001",
|
|
"domain": "email",
|
|
"name": "Email Account Setup, IMAP/SMTP Connection & Polling",
|
|
"purpose": "Configures IMAP/SMTP email accounts, validates TLS certificates, and polls background inbox updates.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/emailInbox.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/email_routes.py:setup_email_routes",
|
|
"routes/email_pollers.py"
|
|
],
|
|
"routes": [
|
|
"/api/email/accounts",
|
|
"/api/email/poll"
|
|
],
|
|
"configuration": [
|
|
"EMAIL_POLL_INTERVAL"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/email_accounts.json"
|
|
],
|
|
"dependencies": [
|
|
"imaplib",
|
|
"smtplib"
|
|
],
|
|
"tests": [
|
|
"tests/test_service_health_email.py",
|
|
"tests/test_active_email_reply_guard.py"
|
|
],
|
|
"documentation": [
|
|
"docs/email-outlook.md"
|
|
],
|
|
"risks": [
|
|
"Account lockouts if bad credentials are repeatedly polled."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/email_routes.py",
|
|
"symbol": "setup_email_routes",
|
|
"line_range": "L1453-L1500",
|
|
"explanation": "Sets up email account management and synchronization routes."
|
|
},
|
|
{
|
|
"path": "routes/email_pollers.py",
|
|
"symbol": "_start_poller",
|
|
"line_range": "L1-L100",
|
|
"explanation": "Background poller for email inbox synchronization."
|
|
},
|
|
{
|
|
"path": "tests/test_service_health_email.py",
|
|
"symbol": "test_email_ok_all_connect",
|
|
"line_range": "L1-L80",
|
|
"explanation": "Tests IMAP connection health probing and status reporting."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires a controlled live IMAP account and network access."
|
|
}
|
|
},
|
|
{
|
|
"id": "EMAIL-002",
|
|
"domain": "email",
|
|
"name": "Email Searching, Threading & Message Operations",
|
|
"purpose": "Parses email headers, folds signatures, groups messages into threads, and executes full-text email search.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/emailLibrary.js",
|
|
"static/js/emailLibrary/state.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/email_routes.py:search_email",
|
|
"src/email_thread_parser.py"
|
|
],
|
|
"routes": [
|
|
"/api/email/search",
|
|
"/api/email/threads",
|
|
"/api/email/messages"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/email_cache.db"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3",
|
|
"email"
|
|
],
|
|
"tests": [
|
|
"tests/test_reply_recipients_js.py",
|
|
"tests/test_signature_fold_js.py"
|
|
],
|
|
"documentation": [
|
|
"docs/email-outlook.md"
|
|
],
|
|
"risks": [
|
|
"Malformed MIME email structures failing HTML sanitization."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/email_routes.py",
|
|
"symbol": "@router.get('/search')",
|
|
"line_range": "L250-L320",
|
|
"explanation": "Executes search across cached email headers and text."
|
|
},
|
|
{
|
|
"path": "src/email_thread_parser.py",
|
|
"symbol": "parse_email_thread",
|
|
"line_range": "L20-L100",
|
|
"explanation": "Builds conversation tree from Message-ID and In-Reply-To headers."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "EMAIL-003",
|
|
"domain": "email",
|
|
"name": "Email Composition, Draft Management & Sending",
|
|
"purpose": "Creates, saves, and dispatches HTML/plaintext email messages via SMTP.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/emailShared.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/email_routes.py:send_email"
|
|
],
|
|
"routes": [
|
|
"/api/email/draft",
|
|
"/api/email/send"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/email_drafts.json"
|
|
],
|
|
"dependencies": [
|
|
"smtplib"
|
|
],
|
|
"tests": [
|
|
"tests/test_schedule_email_offset_normalization.py"
|
|
],
|
|
"documentation": [
|
|
"docs/email-outlook.md"
|
|
],
|
|
"risks": [
|
|
"SMTP connection drop mid-send causing unsent mail state."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/email_routes.py",
|
|
"symbol": "@router.post('/send')",
|
|
"line_range": "L450-L520",
|
|
"explanation": "Sends email message via user SMTP credentials."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires a controlled live SMTP account and network access."
|
|
}
|
|
},
|
|
{
|
|
"id": "EMAIL-004",
|
|
"domain": "email",
|
|
"name": "Email MCP Server & Codex Integration Bridge",
|
|
"purpose": "Exposes constrained email reading and draft capabilities to external Codex / MCP agents with scope checks.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"integrations/codex/scripts/odysseus_api.py"
|
|
],
|
|
"backend_entrypoints": [
|
|
"mcp_servers/email_server.py",
|
|
"routes/codex_routes.py:setup_codex_routes"
|
|
],
|
|
"routes": [
|
|
"/api/codex/email/search",
|
|
"/api/codex/email/send"
|
|
],
|
|
"configuration": [
|
|
"CODEX_API_KEY"
|
|
],
|
|
"persistence": [
|
|
"API token scopes"
|
|
],
|
|
"dependencies": [
|
|
"mcp",
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_mail_cli_recipients.py"
|
|
],
|
|
"documentation": [
|
|
"integrations/codex/README.md"
|
|
],
|
|
"risks": [
|
|
"Unauthorized mail sending if token scopes are improperly scoped."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "mcp_servers/email_server.py",
|
|
"symbol": "EmailMcpServer",
|
|
"line_range": "L20-L120",
|
|
"explanation": "MCP server exposing email tools over stdio/SSE."
|
|
},
|
|
{
|
|
"path": "routes/codex_routes.py",
|
|
"symbol": "setup_codex_routes",
|
|
"line_range": "L30-L110",
|
|
"explanation": "Bridge endpoints for external Codex plugin integration."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CALENDAR-001",
|
|
"domain": "calendar",
|
|
"name": "CalDAV Calendar Synchronization & Account Setup",
|
|
"purpose": "Connects to remote CalDAV servers (Apple iCloud, Nextcloud, Google) to sync calendar event feeds.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/calendar.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/calendar_routes.py:setup_calendar_routes",
|
|
"src/caldav_sync.py:CalDavSync"
|
|
],
|
|
"routes": [
|
|
"/api/calendar/config",
|
|
"/api/calendar/sync"
|
|
],
|
|
"configuration": [
|
|
"CALDAV_URL",
|
|
"CALDAV_USERNAME"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/calendar_config.json"
|
|
],
|
|
"dependencies": [
|
|
"caldav",
|
|
"vobject"
|
|
],
|
|
"tests": [
|
|
"tests/test_caldav_url_hardening.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Invalid SSL certificates on self-hosted CalDAV servers."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/calendar_routes.py",
|
|
"symbol": "setup_calendar_routes",
|
|
"line_range": "L50-L180",
|
|
"explanation": "Exposes CalDAV setup and manual sync trigger routes."
|
|
},
|
|
{
|
|
"path": "src/caldav_sync.py",
|
|
"symbol": "CalDavSync",
|
|
"line_range": "L30-L160",
|
|
"explanation": "Fetches and parses remote iCalendar VEVENT objects."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires a controlled external CalDAV server."
|
|
}
|
|
},
|
|
{
|
|
"id": "CALENDAR-002",
|
|
"domain": "calendar",
|
|
"name": "Calendar Event Operations & iCalendar Parsing",
|
|
"purpose": "Creates, updates, deletes, and displays calendar events with timezone conversion and reminder notifications.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/calendar/reminders.js",
|
|
"static/js/calendar/utils.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/calendar_routes.py:create_event",
|
|
"src/caldav_writeback.py",
|
|
"src/tools/calendar.py"
|
|
],
|
|
"routes": [
|
|
"/api/calendar/events",
|
|
"/api/calendar/events/{event_id}"
|
|
],
|
|
"configuration": [
|
|
"USER_TIMEZONE"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/calendar_events.db"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3",
|
|
"icalendar"
|
|
],
|
|
"tests": [
|
|
"tests/test_calendar_parse_dt_time_first.py",
|
|
"tests/test_calendar_update_event_tz.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Recurring RRULE event expansion calculation bugs across leap years."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/calendar_routes.py",
|
|
"symbol": "@router.get('/events')",
|
|
"line_range": "L220-L310",
|
|
"explanation": "Fetches calendar events for requested date window."
|
|
},
|
|
{
|
|
"path": "src/tools/calendar.py",
|
|
"symbol": "CalendarTool",
|
|
"line_range": "L25-L120",
|
|
"explanation": "Agent tool for creating and modifying calendar entries."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-001",
|
|
"domain": "media",
|
|
"name": "Gallery Image Library & Album Operations",
|
|
"purpose": "Organizes images into custom albums, provides grid browsing, tagging, and album metadata management.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/gallery.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/gallery/gallery_routes.py:setup_gallery_routes"
|
|
],
|
|
"routes": [
|
|
"/api/gallery/library",
|
|
"/api/gallery/albums",
|
|
"/api/gallery/upload"
|
|
],
|
|
"configuration": [
|
|
"GALLERY_STORAGE_DIR"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/gallery/"
|
|
],
|
|
"dependencies": [
|
|
"pillow",
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_gallery_image_endpoint_owner_scope.py",
|
|
"tests/test_gallery_owner_filter_single_user.py"
|
|
],
|
|
"documentation": [
|
|
"docs/gallery.webm"
|
|
],
|
|
"risks": [
|
|
"Thumbnail generation overhead for high-resolution RAW camera images."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/gallery/gallery_routes.py",
|
|
"symbol": "@router.get('/api/gallery/library')",
|
|
"line_range": "L657-L720",
|
|
"explanation": "Fetches image library list with tag filters."
|
|
},
|
|
{
|
|
"path": "static/js/gallery.js",
|
|
"symbol": "initGallery",
|
|
"line_range": "L1-L180",
|
|
"explanation": "Main gallery grid renderer and uploader."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-002",
|
|
"domain": "media",
|
|
"name": "Image Processing, AI Upscaling & Style Transfer",
|
|
"purpose": "Executes local image enhancement, background removal, face sharpening, and AI upscaling operations.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/galleryEditor.js",
|
|
"static/js/editor/ai-tool-runner.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/gallery/gallery_routes.py:ai_upscale",
|
|
"routes/gallery/gallery_routes.py:remove_bg"
|
|
],
|
|
"routes": [
|
|
"/api/gallery/ai-upscale",
|
|
"/api/gallery/style-transfer",
|
|
"/api/image/inpaint",
|
|
"/api/image/remove-bg"
|
|
],
|
|
"configuration": [
|
|
"REALESRGAN_MODEL_PATH"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/gallery/processed/"
|
|
],
|
|
"dependencies": [
|
|
"onnxruntime",
|
|
"opencv-python"
|
|
],
|
|
"tests": [
|
|
"tests/test_sanitize_multimodal_merge.py"
|
|
],
|
|
"documentation": [
|
|
"docs/gallery.webm"
|
|
],
|
|
"risks": [
|
|
"High GPU memory allocation when upscaling 4K images."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/gallery/gallery_routes.py",
|
|
"symbol": "@router.post('/api/gallery/ai-upscale')",
|
|
"line_range": "L544-L580",
|
|
"explanation": "Runs RealESRGAN image upscaling."
|
|
},
|
|
{
|
|
"path": "routes/gallery/gallery_routes.py",
|
|
"symbol": "@router.post('/api/image/remove-bg')",
|
|
"line_range": "L1950-L2010",
|
|
"explanation": "Executes background removal pass."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-003",
|
|
"domain": "media",
|
|
"name": "Interactive Image Canvas Editor & Persisted Drafts",
|
|
"purpose": "Provides full multi-layer raster canvas editor, brush tools, transforms, masks, and draft project persistence.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/galleryEditor.js",
|
|
"static/js/editor/history-panel.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/editor_draft_routes.py:setup_editor_draft_routes"
|
|
],
|
|
"routes": [
|
|
"/api/editor/drafts",
|
|
"/api/editor/drafts/{draft_id}"
|
|
],
|
|
"configuration": [
|
|
"MAX_DRAFT_PROJECTS"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/editor_drafts/"
|
|
],
|
|
"dependencies": [
|
|
"HTML5 Canvas API",
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_canvas_coords_empty_touches_js.py",
|
|
"tests/test_snap_other_layers_nonarray_js.py"
|
|
],
|
|
"documentation": [
|
|
"docs/gallery.webm"
|
|
],
|
|
"risks": [
|
|
"Browser memory leak if multi-gigabyte layer undo buffers are kept indefinitely."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/editor_draft_routes.py",
|
|
"symbol": "setup_editor_draft_routes",
|
|
"line_range": "L30-L110",
|
|
"explanation": "API routes for saving and loading canvas project drafts."
|
|
},
|
|
{
|
|
"path": "static/js/editor/history-panel.js",
|
|
"symbol": "HistoryManager",
|
|
"line_range": "L1-L90",
|
|
"explanation": "Canvas undo/redo stack manager."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-004",
|
|
"domain": "media",
|
|
"name": "Text-to-Speech (TTS) Synthesis Service",
|
|
"purpose": "Synthesizes spoken audio from text using local Kokoro, EdgeTTS, or OpenAI TTS engines.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/tts-ai.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/tts_routes.py:setup_tts_routes",
|
|
"services/tts/tts_service.py:TTSService"
|
|
],
|
|
"routes": [
|
|
"/api/tts/synthesize",
|
|
"/api/tts/stats"
|
|
],
|
|
"configuration": [
|
|
"TTS_PROVIDER",
|
|
"TTS_VOICE"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/tts_cache/"
|
|
],
|
|
"dependencies": [
|
|
"soundfile",
|
|
"edge-tts"
|
|
],
|
|
"tests": [
|
|
"tests/test_tts_available_nonstring_provider.py",
|
|
"tests/test_tts_cache_stats.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Audio synthesis latency on CPU-only hardware setups."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/tts_routes.py",
|
|
"symbol": "@router.post('/synthesize')",
|
|
"line_range": "L30-L75",
|
|
"explanation": "Synthesizes TTS audio clip."
|
|
},
|
|
{
|
|
"path": "services/tts/tts_service.py",
|
|
"symbol": "TTSService",
|
|
"line_range": "L25-L140",
|
|
"explanation": "Provider abstraction layer for audio speech generation."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-005",
|
|
"domain": "media",
|
|
"name": "Speech-to-Text (STT) Audio Transcription Service",
|
|
"purpose": "Transcribes user audio recordings into text using faster-whisper or local speech models.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/voiceRecorder.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/stt_routes.py:setup_stt_routes",
|
|
"services/stt/stt_service.py:STTService"
|
|
],
|
|
"routes": [
|
|
"/api/stt/transcribe",
|
|
"/api/stt/stats"
|
|
],
|
|
"configuration": [
|
|
"STT_PROVIDER",
|
|
"WHISPER_MODEL_SIZE"
|
|
],
|
|
"persistence": [
|
|
"Temporary audio buffer"
|
|
],
|
|
"dependencies": [
|
|
"faster-whisper",
|
|
"ffmpeg-python"
|
|
],
|
|
"tests": [
|
|
"tests/test_stt_leak.py",
|
|
"tests/test_speech_service_toggles.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Missing ffmpeg system dependency prevents audio format decoding."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/stt_routes.py",
|
|
"symbol": "@router.post('/transcribe')",
|
|
"line_range": "L25-L55",
|
|
"explanation": "Accepts multipart audio file and returns transcription text."
|
|
},
|
|
{
|
|
"path": "services/stt/stt_service.py",
|
|
"symbol": "STTService",
|
|
"line_range": "L20-L110",
|
|
"explanation": "Whisper audio transcription engine wrapper."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-006",
|
|
"domain": "media",
|
|
"name": "Digital Signature Stamp Storage & Placement",
|
|
"purpose": "Stores transparent PNG user signatures and stamps for placement onto PDF forms and documents.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/signature.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/signature_routes.py:setup_signature_routes"
|
|
],
|
|
"routes": [
|
|
"/api/signatures",
|
|
"/api/signatures/{sig_id}"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/signatures/"
|
|
],
|
|
"dependencies": [
|
|
"pillow"
|
|
],
|
|
"tests": [
|
|
"tests/test_signature_route_hardening.py",
|
|
"tests/test_signature_settings_dom_xss.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Cross-site scripting if signature image titles contain unescaped user input."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/signature_routes.py",
|
|
"symbol": "setup_signature_routes",
|
|
"line_range": "L30-L120",
|
|
"explanation": "CRUD endpoints for managing user signature PNG stamps."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-007",
|
|
"domain": "media",
|
|
"name": "Generated Image Artifact Route & MCP Integration",
|
|
"purpose": "Serves generated AI artwork artifacts and integrates with image generation MCP server.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chat.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"app.py:serve_generated_image",
|
|
"src/generated_images.py",
|
|
"mcp_servers/image_gen_server.py"
|
|
],
|
|
"routes": [
|
|
"/api/generated-image/{filename}"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/generated_images/"
|
|
],
|
|
"dependencies": [
|
|
"pillow",
|
|
"mcp"
|
|
],
|
|
"tests": [
|
|
"tests/test_image_models_nondict_system.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Path traversal vulnerability if filename parameter is un-sanitized."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "app.py",
|
|
"symbol": "serve_generated_image",
|
|
"line_range": "L499-L520",
|
|
"explanation": "Serves generated image artifacts with cache headers."
|
|
},
|
|
{
|
|
"path": "src/generated_images.py",
|
|
"symbol": "resolve_generated_image_path",
|
|
"line_range": "L20-L32",
|
|
"explanation": "Confines requested image path within artifacts directory."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEDIA-008",
|
|
"domain": "media",
|
|
"name": "Native MLX Image Bridge (macOS Apple Silicon)",
|
|
"purpose": "Native Apple Swift bridge for hardware-accelerated diffusion and MLX image colorization on macOS.",
|
|
"status": "experimental",
|
|
"frontend_entrypoints": [
|
|
"static/js/editor/ai-tools-misc.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"swift/odysseus-mlx-image-bridge/Package.swift",
|
|
"scripts/mlx_image_server.py",
|
|
"scripts/diffusion_server.py"
|
|
],
|
|
"routes": [
|
|
"/api/image/mlx-colorize"
|
|
],
|
|
"configuration": [
|
|
"ENABLE_MLX_ACCELERATION"
|
|
],
|
|
"persistence": [
|
|
"Build artifact binary"
|
|
],
|
|
"dependencies": [
|
|
"Swift",
|
|
"MLX Framework"
|
|
],
|
|
"tests": [
|
|
"tests/helpers/import_state.py"
|
|
],
|
|
"documentation": [
|
|
"swift/odysseus-mlx-image-bridge/Package.swift"
|
|
],
|
|
"risks": [
|
|
"Requires macOS host with Apple Silicon M-series chip and compiled Swift binary."
|
|
],
|
|
"unknowns": [
|
|
"Binary build requires Xcode command line tools build step (`build-macos-app.sh`)."
|
|
],
|
|
"evidence": [
|
|
{
|
|
"path": "swift/odysseus-mlx-image-bridge/Package.swift",
|
|
"symbol": "Package",
|
|
"line_range": "L1-L30",
|
|
"explanation": "Swift package manifest for native MLX image bridge."
|
|
},
|
|
{
|
|
"path": "scripts/mlx_image_server.py",
|
|
"symbol": "main",
|
|
"line_range": "L20-L90",
|
|
"explanation": "Python daemon wrapping native Swift MLX binary."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires Apple Silicon, macOS tooling, and the compiled MLX bridge."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-001",
|
|
"domain": "security",
|
|
"name": "Authentication, Session Cookies & User Management",
|
|
"purpose": "Handles bcrypt password hashing, session cookie issuance, authentication enforcement, and user administration.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/login.html",
|
|
"static/js/admin.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/auth_routes.py:setup_auth_routes",
|
|
"core/auth.py:AuthManager"
|
|
],
|
|
"routes": [
|
|
"/api/auth/login",
|
|
"/api/auth/me",
|
|
"/api/auth/users",
|
|
"/api/auth/logout"
|
|
],
|
|
"configuration": [
|
|
"AUTH_ENABLED",
|
|
"SESSION_COOKIE_NAME"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/auth.db"
|
|
],
|
|
"dependencies": [
|
|
"bcrypt",
|
|
"itsdangerous"
|
|
],
|
|
"tests": [
|
|
"tests/test_rename_user_owner_sync.py",
|
|
"tests/test_reserved_username_admin_escalation.py"
|
|
],
|
|
"documentation": [
|
|
"THREAT_MODEL.md",
|
|
"SECURITY.md"
|
|
],
|
|
"risks": [
|
|
"Cookie session hijack if deployed over unencrypted HTTP without HTTPS cookie flags."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/auth_routes.py",
|
|
"symbol": "@router.post('/login')",
|
|
"line_range": "L100-L180",
|
|
"explanation": "Authenticates credentials and sets session cookie."
|
|
},
|
|
{
|
|
"path": "core/auth.py",
|
|
"symbol": "AuthManager",
|
|
"line_range": "L40-L260",
|
|
"explanation": "Handles user creation, password verification, and session tokens."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-002",
|
|
"domain": "security",
|
|
"name": "System Vault Encrypted Secret Storage",
|
|
"purpose": "Encrypts API keys, passphrases, and third-party secrets on disk using AES-GCM / PBKDF2 key derivation.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/settings.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/vault_routes.py:setup_vault_routes",
|
|
"src/secret_storage.py:SecretVault",
|
|
"src/tools/vault.py"
|
|
],
|
|
"routes": [
|
|
"/api/vault/config",
|
|
"/api/vault/unlock",
|
|
"/api/vault/lock"
|
|
],
|
|
"configuration": [
|
|
"VAULT_SALT"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/vault.enc"
|
|
],
|
|
"dependencies": [
|
|
"cryptography"
|
|
],
|
|
"tests": [
|
|
"tests/test_vault_password_not_in_argv.py"
|
|
],
|
|
"documentation": [
|
|
"THREAT_MODEL.md"
|
|
],
|
|
"risks": [
|
|
"Loss of vault master passphrase renders all encrypted secrets permanently unrecoverable."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/vault_routes.py",
|
|
"symbol": "setup_vault_routes",
|
|
"line_range": "L126-L229",
|
|
"explanation": "Admin routes for vault configuration, login, unlock, lock, and logout."
|
|
},
|
|
{
|
|
"path": "src/secret_storage.py",
|
|
"symbol": "SecretStorage",
|
|
"line_range": "L57-L87",
|
|
"explanation": "Fernet symmetric key DB secret encryption."
|
|
},
|
|
{
|
|
"path": "tests/test_vault_password_not_in_argv.py",
|
|
"symbol": "test_bw_password_not_in_argv",
|
|
"line_range": "L1-L117",
|
|
"explanation": "Verifies master password is fed via stdin and never appears in process argv."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires installed Bitwarden CLI (`bw`) executable."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-003",
|
|
"domain": "security",
|
|
"name": "API Token Management & Scope Access Control",
|
|
"purpose": "Generates scoped API bearer tokens (read/write/admin) for external tool and script authentication.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/settings.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/api_token_routes.py:setup_api_token_routes",
|
|
"core/database.py:ApiToken"
|
|
],
|
|
"routes": [
|
|
"/api/tokens",
|
|
"/api/tokens/{token_id}"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/odysseus.db (api_tokens table)"
|
|
],
|
|
"dependencies": [
|
|
"sqlalchemy",
|
|
"secrets"
|
|
],
|
|
"tests": [
|
|
"tests/test_api_key_file_permissions.py"
|
|
],
|
|
"documentation": [
|
|
"SECURITY.md"
|
|
],
|
|
"risks": [
|
|
"Leaked API bearer tokens with excessive permission scopes."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/api_token_routes.py",
|
|
"symbol": "setup_api_token_routes",
|
|
"line_range": "L30-L150",
|
|
"explanation": "Exposes API token creation, scope assignment, and revocation."
|
|
},
|
|
{
|
|
"path": "core/database.py",
|
|
"symbol": "ApiToken",
|
|
"line_range": "L50-L90",
|
|
"explanation": "SQLAlchemy ORM schema for API tokens and permissions."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-004",
|
|
"domain": "security",
|
|
"name": "Prompt Security & Injection Defense Engine",
|
|
"purpose": "Scans system prompts and external inputs for prompt injection attempts, jailbreaks, and sensitive data leaks.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/chat.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/prompt_security.py:sanitize_prompt",
|
|
"src/tool_security.py:validate_tool_input"
|
|
],
|
|
"routes": [
|
|
"Implicit security inspection"
|
|
],
|
|
"configuration": [
|
|
"ENABLE_PROMPT_SANITY_CHECK"
|
|
],
|
|
"persistence": [],
|
|
"dependencies": [
|
|
"re"
|
|
],
|
|
"tests": [
|
|
"tests/test_skill_index_prompt_injection.py",
|
|
"tests/test_tool_output_prompt_injection.py"
|
|
],
|
|
"documentation": [
|
|
"THREAT_MODEL.md"
|
|
],
|
|
"risks": [
|
|
"False positives blocking legitimate complex coding or security prompts."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/prompt_security.py",
|
|
"symbol": "untrusted_context_message",
|
|
"line_range": "L64-L86",
|
|
"explanation": "Wraps untrusted context with guard delimiters and sets metadata.trusted = False."
|
|
},
|
|
{
|
|
"path": "src/tool_security.py",
|
|
"symbol": "NON_ADMIN_BLOCKED_TOOLS",
|
|
"line_range": "L42-L78",
|
|
"explanation": "Enforces tool execution safety for non-admin user roles."
|
|
},
|
|
{
|
|
"path": "tests/test_skill_index_prompt_injection.py",
|
|
"symbol": "test_skill_index",
|
|
"line_range": "L1-L208",
|
|
"explanation": "Verifies skill index descriptions cannot leak into trusted system prompts."
|
|
},
|
|
{
|
|
"path": "tests/test_tool_output_prompt_injection.py",
|
|
"symbol": "test_tool_output",
|
|
"line_range": "L1-L50",
|
|
"explanation": "Tool output injection guards."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-005",
|
|
"domain": "security",
|
|
"name": "URL & Path Confinement Security Guards",
|
|
"purpose": "Prevents SSRF attacks and path traversal by validating target IP addresses and resolving symlinks.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/fileHandler.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"src/url_security.py:validate_url",
|
|
"src/url_safety.py",
|
|
"core/log_safety.py"
|
|
],
|
|
"routes": [
|
|
"Implicit guard functions"
|
|
],
|
|
"configuration": [
|
|
"ALLOWED_DOMAINS_WHITELIST"
|
|
],
|
|
"persistence": [],
|
|
"dependencies": [
|
|
"ipaddress",
|
|
"urllib.parse"
|
|
],
|
|
"tests": [
|
|
"tests/test_url_safety.py",
|
|
"tests/test_tool_path_confinement.py",
|
|
"tests/test_workspace_confine.py"
|
|
],
|
|
"documentation": [
|
|
"THREAT_MODEL.md"
|
|
],
|
|
"risks": [
|
|
"DNS rebinding attacks if IP address is re-resolved post-validation."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "src/url_safety.py",
|
|
"symbol": "check_outbound_url",
|
|
"line_range": "L60-L108",
|
|
"explanation": "Rejects non-HTTP(S) schemes, link-local, cloud metadata SSRF addresses."
|
|
},
|
|
{
|
|
"path": "src/url_security.py",
|
|
"symbol": "validate_public_http_url",
|
|
"line_range": "L81-L94",
|
|
"explanation": "Validates public-facing endpoints."
|
|
},
|
|
{
|
|
"path": "tests/test_url_safety.py",
|
|
"symbol": "test_url_safety",
|
|
"line_range": "L1-L117",
|
|
"explanation": "Scheme validation, cloud metadata SSRF rejection, IP classification."
|
|
},
|
|
{
|
|
"path": "tests/test_tool_path_confinement.py",
|
|
"symbol": "test_path_confinement",
|
|
"line_range": "L1-L50",
|
|
"explanation": "Path traversal checks."
|
|
},
|
|
{
|
|
"path": "tests/test_workspace_confine.py",
|
|
"symbol": "test_workspace_confine",
|
|
"line_range": "L1-L50",
|
|
"explanation": "Workspace confinement checks."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-006",
|
|
"domain": "security",
|
|
"name": "HTTP Security Headers Middleware",
|
|
"purpose": "Injects standard OWASP HTTP security headers (CSP, HSTS, X-Content-Type-Options, X-Frame-Options).",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/app.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"core/middleware.py:SecurityHeadersMiddleware"
|
|
],
|
|
"routes": [
|
|
"Applies globally to all routes"
|
|
],
|
|
"configuration": [
|
|
"CSP_NONCE_ENABLED"
|
|
],
|
|
"persistence": [],
|
|
"dependencies": [
|
|
"starlette.middleware.base"
|
|
],
|
|
"tests": [
|
|
"tests/test_security_headers_middleware.py",
|
|
"tests/test_security_headers_pdf_preview.py"
|
|
],
|
|
"documentation": [
|
|
"SECURITY.md"
|
|
],
|
|
"risks": [
|
|
"Strict Content Security Policy (CSP) blocking third-party embedded web resources."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "core/middleware.py",
|
|
"symbol": "SecurityHeadersMiddleware",
|
|
"line_range": "L40-L110",
|
|
"explanation": "Sets strict security headers and CSP nonces on HTTP responses."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "SECURITY-007",
|
|
"domain": "security",
|
|
"name": "Admin System Data Wipe ('Danger Zone')",
|
|
"purpose": "Provides administrative reset operations to wipe sessions, cache, uploaded files, or factory reset state.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/admin.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/admin_wipe/admin_wipe_routes.py:setup_admin_wipe_routes"
|
|
],
|
|
"routes": [
|
|
"/api/admin/wipe/{kind}"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"ALL storage locations"
|
|
],
|
|
"dependencies": [
|
|
"os",
|
|
"shutil"
|
|
],
|
|
"tests": [
|
|
"tests/test_session_ghost_delete.py"
|
|
],
|
|
"documentation": [
|
|
"THREAT_MODEL.md"
|
|
],
|
|
"risks": [
|
|
"Accidental catastrophic data loss if triggered without user confirmation."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/admin_wipe/admin_wipe_routes.py",
|
|
"symbol": "@router.delete('/wipe/{kind}')",
|
|
"line_range": "L71-L130",
|
|
"explanation": "Executes systemic data wipe based on requested scope."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-001",
|
|
"domain": "frontend",
|
|
"name": "Single Page Application Shell & Client Router",
|
|
"purpose": "Main HTML5 SPA shell, DOM lifecycle initializers, tab navigation, and deep-link route handlers.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/index.html",
|
|
"static/app.js",
|
|
"static/js/init.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"app.py:serve_index"
|
|
],
|
|
"routes": [
|
|
"/",
|
|
"/notes",
|
|
"/calendar",
|
|
"/cookbook",
|
|
"/email",
|
|
"/memory",
|
|
"/gallery",
|
|
"/tasks",
|
|
"/library"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"static/index.html"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla HTML5/JS"
|
|
],
|
|
"tests": [
|
|
"tests/test_app_static_mime.py",
|
|
"tests/test_serve_html_with_nonce.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Stale browser static cache if asset hashing is omitted during deployment."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/index.html",
|
|
"symbol": "index.html",
|
|
"line_range": "L1-L200",
|
|
"explanation": "Main SPA entry point containing modal roots and CSS bundles."
|
|
},
|
|
{
|
|
"path": "app.py",
|
|
"symbol": "serve_index",
|
|
"line_range": "L867-L878",
|
|
"explanation": "Serves index.html with dynamically generated CSP nonces."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-002",
|
|
"domain": "frontend",
|
|
"name": "Dynamic Theme, Color System & Custom Fonts",
|
|
"purpose": "Supports dark/light themes, custom CSS variables, color picker controls, and user font uploads.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/theme.js",
|
|
"static/style.css",
|
|
"static/js/colorPicker.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/font_routes.py:setup_font_routes",
|
|
"routes/prefs_routes.py:setup_prefs_routes"
|
|
],
|
|
"routes": [
|
|
"/api/font/custom",
|
|
"/api/prefs"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/user_prefs.json",
|
|
"static/fonts/custom/"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla CSS",
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_prefs_atomic_write.py",
|
|
"tests/test_select_dropdown_theme_css.py"
|
|
],
|
|
"documentation": [
|
|
"docs/theme.webm"
|
|
],
|
|
"risks": [
|
|
"Flash of unstyled content (FOUC) on slow connections."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/theme.js",
|
|
"symbol": "applyTheme",
|
|
"line_range": "L1-L90",
|
|
"explanation": "Applies custom HSL theme variables to DOM document root."
|
|
},
|
|
{
|
|
"path": "routes/font_routes.py",
|
|
"symbol": "setup_font_routes",
|
|
"line_range": "L20-L55",
|
|
"explanation": "Allows uploading and serving custom WOFF2 font files."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-003",
|
|
"domain": "frontend",
|
|
"name": "Window Manager, Tile Layout & Modal Control System",
|
|
"purpose": "Manages draggable tool windows, snapped multi-tile viewports, modal dialog Z-ordering, and ESC key stacks.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/modalManager.js",
|
|
"static/js/tileManager.js",
|
|
"static/js/windowDrag.js",
|
|
"static/js/windowResize.js",
|
|
"static/js/escMenuStack.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"None (Client UI subsystem)"
|
|
],
|
|
"routes": [],
|
|
"configuration": [
|
|
"localStorage: tile_layout_state"
|
|
],
|
|
"persistence": [
|
|
"Browser localStorage"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla JS DOM event listeners"
|
|
],
|
|
"tests": [
|
|
"tests/test_portal_dropdown_z_js.py",
|
|
"tests/test_tile_manager_snap_zones_js.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Overlap artifacts when opening many simultaneous tool floating windows."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/modalManager.js",
|
|
"symbol": "ModalManager",
|
|
"line_range": "L1-L140",
|
|
"explanation": "Controls modal open/close transitions and focus trapping."
|
|
},
|
|
{
|
|
"path": "static/js/tileManager.js",
|
|
"symbol": "TileManager",
|
|
"line_range": "L1-L180",
|
|
"explanation": "Handles viewport split-pane grid arrangements."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-004",
|
|
"domain": "frontend",
|
|
"name": "Global Keyboard Shortcuts & Accessibility Controls",
|
|
"purpose": "Provides configurable hotkeys (Ctrl+K search, Esc close, Alt+1-9 tabs) and high-contrast accessibility options.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/keyboard-shortcuts.js",
|
|
"static/js/a11y.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"None (Client UI subsystem)"
|
|
],
|
|
"routes": [],
|
|
"configuration": [
|
|
"localStorage: user_hotkeys"
|
|
],
|
|
"persistence": [
|
|
"Browser localStorage"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla JS"
|
|
],
|
|
"tests": [
|
|
"tests/test_keyboard_shortcuts.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Browser keybinding collisions with browser default hotkeys."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/keyboard-shortcuts.js",
|
|
"symbol": "initShortcuts",
|
|
"line_range": "L1-L110",
|
|
"explanation": "Binds global keydown handlers for system shortcuts."
|
|
},
|
|
{
|
|
"path": "static/js/a11y.js",
|
|
"symbol": "initA11y",
|
|
"line_range": "L1-L80",
|
|
"explanation": "Applies ARIA roles and dyslexic font toggles."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-005",
|
|
"domain": "frontend",
|
|
"name": "Markdown, LaTeX & Code Block Streaming Renderer",
|
|
"purpose": "Parses incoming SSE markdown streams, renders KaTeX math formulas, syntax-highlighted code, and interactive runners.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/markdown.js",
|
|
"static/js/streamingRenderer.js",
|
|
"static/js/streamingSegmenter.js",
|
|
"static/js/codeRunner.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"None (Client rendering subsystem)"
|
|
],
|
|
"routes": [],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"Browser DOM"
|
|
],
|
|
"dependencies": [
|
|
"highlight.js",
|
|
"katex"
|
|
],
|
|
"tests": [
|
|
"tests/streaming/segmenter.test.mjs",
|
|
"tests/test_streaming_segmenter_js.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"DOM thrashing if streaming segmenter updates UI too frequently."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/markdown.js",
|
|
"symbol": "renderMarkdown",
|
|
"line_range": "L1-L200",
|
|
"explanation": "Converts markdown prose to HTML nodes with syntax highlighting."
|
|
},
|
|
{
|
|
"path": "static/js/streamingSegmenter.js",
|
|
"symbol": "Segmenter",
|
|
"line_range": "L1-L150",
|
|
"explanation": "Parses un-closed markdown fences during live stream."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-006",
|
|
"domain": "frontend",
|
|
"name": "Interactive Tour & Guided Onboarding System",
|
|
"purpose": "Presents interactive step-by-step feature tours and UI tooltip hints for new users.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/tourHints.js",
|
|
"static/js/tourAutoplay.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"None (Client UI subsystem)"
|
|
],
|
|
"routes": [],
|
|
"configuration": [
|
|
"localStorage: tour_completed"
|
|
],
|
|
"persistence": [
|
|
"Browser localStorage"
|
|
],
|
|
"dependencies": [
|
|
"Vanilla JS"
|
|
],
|
|
"tests": [
|
|
"tests/test_task_routes.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Tour step misalignment if window is resized mid-tour."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "static/js/tourHints.js",
|
|
"symbol": "startTour",
|
|
"line_range": "L1-L120",
|
|
"explanation": "Renders guided feature tour overlays over target UI elements."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "FRONTEND-007",
|
|
"domain": "frontend",
|
|
"name": "Background Effects Prototyping Sandbox",
|
|
"purpose": "Standalone sandbox page for prototyping visual background animations, waves, and whirlpool effects.",
|
|
"status": "dead-code-candidate",
|
|
"frontend_entrypoints": [
|
|
"static/wave-variants.html",
|
|
"static/whirlpool-variants.html"
|
|
],
|
|
"backend_entrypoints": [
|
|
"app.py:serve_backgrounds"
|
|
],
|
|
"routes": [
|
|
"/backgrounds"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"None"
|
|
],
|
|
"dependencies": [
|
|
"HTML5 Canvas",
|
|
"WebGL"
|
|
],
|
|
"tests": [],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"High GPU utilization when rendering complex shader wave animations."
|
|
],
|
|
"unknowns": [
|
|
"Route `/backgrounds` in app.py L918 attempts to serve `static/backgrounds.html` which is missing from disk; variant templates `wave-variants.html` and `whirlpool-variants.html` exist."
|
|
],
|
|
"evidence": [
|
|
{
|
|
"path": "app.py",
|
|
"symbol": "serve_backgrounds",
|
|
"line_range": "L915-L918",
|
|
"explanation": "Serves visual background sandbox HTML page route."
|
|
},
|
|
{
|
|
"path": "static/wave-variants.html",
|
|
"symbol": "wave-variants.html",
|
|
"line_range": "L1-L150",
|
|
"explanation": "Interactive background effect prototyping sandbox variant."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E1",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-001",
|
|
"domain": "platform",
|
|
"name": "Application Initialization & Lifespan Management",
|
|
"purpose": "Orchestrates server startup, database table migration, background daemon initialization, and clean shutdown.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"app.py"
|
|
],
|
|
"backend_entrypoints": [
|
|
"app.py:_lifespan",
|
|
"src/app_initializer.py:initialize_app"
|
|
],
|
|
"routes": [
|
|
"App startup lifespan"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/"
|
|
],
|
|
"dependencies": [
|
|
"asyncio",
|
|
"logging"
|
|
],
|
|
"tests": [
|
|
"tests/test_app_helpers.py"
|
|
],
|
|
"documentation": [
|
|
"docs/setup.md"
|
|
],
|
|
"risks": [
|
|
"Un-handled exceptions during startup halt application launch."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "app.py",
|
|
"symbol": "_lifespan",
|
|
"line_range": "L996-L1030",
|
|
"explanation": "FastAPI lifespan context manager executing startup tasks."
|
|
},
|
|
{
|
|
"path": "src/app_initializer.py",
|
|
"symbol": "initialize_app",
|
|
"line_range": "L29-L125",
|
|
"explanation": "Initializes app directories, DB schemas, and logging."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-002",
|
|
"domain": "platform",
|
|
"name": "System Health, Readiness & Version Monitoring APIs",
|
|
"purpose": "Exposes Liveness (/api/health), Readiness (/api/ready), App Version (/api/version), and Client Perf APIs.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/admin.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"app.py:health_check",
|
|
"app.py:readiness_check",
|
|
"app.py:get_version",
|
|
"src/readiness.py"
|
|
],
|
|
"routes": [
|
|
"/api/health",
|
|
"/api/ready",
|
|
"/api/version",
|
|
"/api/runtime",
|
|
"/api/client-perf"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [],
|
|
"dependencies": [
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/test_readiness.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Readiness check delays if verifying connectivity to offline remote endpoints."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "app.py",
|
|
"symbol": "readiness_check",
|
|
"line_range": "L963-L973",
|
|
"explanation": "Performs system component integrity check."
|
|
},
|
|
{
|
|
"path": "src/readiness.py",
|
|
"symbol": "check_readiness",
|
|
"line_range": "L15-L61",
|
|
"explanation": "Checks database, storage, and key paths for read/write access."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-003",
|
|
"domain": "platform",
|
|
"name": "Database Schema, Migrations & SQLite Persistence",
|
|
"purpose": "Defines core relational tables (users, tokens, tasks, sessions) and executes automated SQLite schema upgrades.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"scripts/update_database.py"
|
|
],
|
|
"backend_entrypoints": [
|
|
"core/database.py:init_db",
|
|
"scripts/update_database.py:run_migrations",
|
|
"src/database.py"
|
|
],
|
|
"routes": [
|
|
"Implicit DB queries"
|
|
],
|
|
"configuration": [
|
|
"DATABASE_URL"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/odysseus.db"
|
|
],
|
|
"dependencies": [
|
|
"sqlalchemy",
|
|
"alembic",
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_sqlite_foreign_keys.py",
|
|
"tests/test_update_database_script.py",
|
|
"tests/test_app_db_permissions.py"
|
|
],
|
|
"documentation": [
|
|
"docs/setup.md"
|
|
],
|
|
"risks": [
|
|
"SQLite file lock contention under high concurrent write loads."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "core/database.py",
|
|
"symbol": "init_db",
|
|
"line_range": "L40-L120",
|
|
"explanation": "Creates ORM tables and establishes connection pool."
|
|
},
|
|
{
|
|
"path": "scripts/update_database.py",
|
|
"symbol": "run_migrations",
|
|
"line_range": "L20-L110",
|
|
"explanation": "Applies missing schema columns and indices."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-004",
|
|
"domain": "platform",
|
|
"name": "User Data Export & Import Backup Infrastructure",
|
|
"purpose": "Exports complete user workspace state (sessions, memory, skills, notes, presets) into a zip archive.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/settings.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/backup_routes.py:setup_backup_routes",
|
|
"scripts/odysseus-backup"
|
|
],
|
|
"routes": [
|
|
"/api/backup/export",
|
|
"/api/backup/import"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"ZIP archive files"
|
|
],
|
|
"dependencies": [
|
|
"zipfile",
|
|
"json"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_preset_cli_store.py"
|
|
],
|
|
"documentation": [
|
|
"docs/backup-restore.md"
|
|
],
|
|
"risks": [
|
|
"Corrupt archive files causing partial data restore."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/backup_routes.py",
|
|
"symbol": "setup_backup_routes",
|
|
"line_range": "L30-L140",
|
|
"explanation": "Handles workspace data export and import upload unpack."
|
|
},
|
|
{
|
|
"path": "docs/backup-restore.md",
|
|
"symbol": "Documentation",
|
|
"line_range": "L1-L50",
|
|
"explanation": "Backup and restore operational documentation."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-005",
|
|
"domain": "platform",
|
|
"name": "File Cleanup & Storage Maintenance Engine",
|
|
"purpose": "Scans data directories for orphaned files, old uploads, temporary vision images, and frees disk space.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/storage.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/cleanup/cleanup_routes.py:setup_cleanup_routes",
|
|
"src/cleanup_service.py",
|
|
"src/session_image_cleanup.py"
|
|
],
|
|
"routes": [
|
|
"/api/cleanup/preview",
|
|
"/api/cleanup"
|
|
],
|
|
"configuration": [
|
|
"CLEANUP_RETENTION_DAYS"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/uploads/"
|
|
],
|
|
"dependencies": [
|
|
"os",
|
|
"shutil"
|
|
],
|
|
"tests": [
|
|
"tests/test_session_actions_cleanup.py",
|
|
"tests/test_session_image_cleanup.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Deletes files uploaded in active sessions if retention window is set too short."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/cleanup/cleanup_routes.py",
|
|
"symbol": "@router.get('/preview')",
|
|
"line_range": "L22-L37",
|
|
"explanation": "Previews reclaimable disk space across storage directories."
|
|
},
|
|
{
|
|
"path": "src/cleanup_service.py",
|
|
"symbol": "CleanupService",
|
|
"line_range": "L25-L120",
|
|
"explanation": "Executes filesystem purge of orphaned asset files."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-006",
|
|
"domain": "platform",
|
|
"name": "System Health & RAG Diagnostic Suite",
|
|
"purpose": "Executes real-time integrity diagnostics across ChromaDB, SearXNG, local models, and network interfaces.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/settings.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/diagnostics_routes.py:setup_diagnostics_routes",
|
|
"src/service_health.py"
|
|
],
|
|
"routes": [
|
|
"/api/diagnostics"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [],
|
|
"dependencies": [
|
|
"httpx",
|
|
"chromadb"
|
|
],
|
|
"tests": [
|
|
"tests/test_service_health_collect.py",
|
|
"tests/test_service_health_chromadb.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Diagnostic timeout if external search provider is unreachable."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/diagnostics_routes.py",
|
|
"symbol": "setup_diagnostics_routes",
|
|
"line_range": "L30-L100",
|
|
"explanation": "Runs subsystem health check suite."
|
|
},
|
|
{
|
|
"path": "src/service_health.py",
|
|
"symbol": "collect_health_status",
|
|
"line_range": "L20-L150",
|
|
"explanation": "Inspects vector database, email, search, and local provider status."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-007",
|
|
"domain": "platform",
|
|
"name": "Desktop CLI Utilities & Shell Integration Tools",
|
|
"purpose": "Provides command-line interface tools (`odysseus`, `odysseus-mcp`, `odysseus-mail`) for terminal usage.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"scripts/odysseus",
|
|
"scripts/odysseus-mcp",
|
|
"scripts/odysseus-mail",
|
|
"scripts/odysseus-calendar"
|
|
],
|
|
"backend_entrypoints": [
|
|
"scripts/_lib/cli.py:main"
|
|
],
|
|
"routes": [
|
|
"CLI commands"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"CLI configuration"
|
|
],
|
|
"dependencies": [
|
|
"urllib",
|
|
"json"
|
|
],
|
|
"tests": [
|
|
"tests/cli/test_sessions_cli.py",
|
|
"tests/cli/test_mail_cli_recipients.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Outdated CLI scripts if backend API schemas change."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "scripts/_lib/cli.py",
|
|
"symbol": "main",
|
|
"line_range": "L15-L110",
|
|
"explanation": "Shared CLI framework for terminal helper commands."
|
|
},
|
|
{
|
|
"path": "scripts/odysseus",
|
|
"symbol": "odysseus",
|
|
"line_range": "L1-L50",
|
|
"explanation": "Main terminal launcher script."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-008",
|
|
"domain": "platform",
|
|
"name": "Desktop Companion App Integration",
|
|
"purpose": "Provides API routes and pairing mechanisms for the native macOS/desktop menu bar companion app.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"companion/README.md"
|
|
],
|
|
"backend_entrypoints": [
|
|
"companion/pairing.py",
|
|
"companion/routes.py:setup_companion_routes"
|
|
],
|
|
"routes": [
|
|
"/companion/pair",
|
|
"/companion/status"
|
|
],
|
|
"configuration": [
|
|
"COMPANION_SECRET_KEY"
|
|
],
|
|
"persistence": [
|
|
"companion_pairing.json"
|
|
],
|
|
"dependencies": [
|
|
"fastapi"
|
|
],
|
|
"tests": [
|
|
"tests/helpers/import_state.py"
|
|
],
|
|
"documentation": [
|
|
"companion/README.md"
|
|
],
|
|
"risks": [
|
|
"Pairing code expiration timing window."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "companion/routes.py",
|
|
"symbol": "setup_companion_routes",
|
|
"line_range": "L20-L120",
|
|
"explanation": "Endpoints for pairing and status sync with desktop companion."
|
|
},
|
|
{
|
|
"path": "companion/pairing.py",
|
|
"symbol": "PairingManager",
|
|
"line_range": "L15-L80",
|
|
"explanation": "Generates and validates companion pairing codes."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-009",
|
|
"domain": "platform",
|
|
"name": "Docker Containerization & GPU Hardware Manifests",
|
|
"purpose": "Provides multi-stage Dockerfile and Docker Compose manifests for CPU, NVIDIA CUDA, and AMD ROCm GPUs.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"Dockerfile",
|
|
"docker-compose.yml",
|
|
"docker-compose.gpu-nvidia.yml",
|
|
"docker-compose.gpu-amd.yml"
|
|
],
|
|
"backend_entrypoints": [
|
|
"docker/entrypoint.sh"
|
|
],
|
|
"routes": [
|
|
"Containerized application"
|
|
],
|
|
"configuration": [
|
|
"DOCKER_GPU_VENDOR"
|
|
],
|
|
"persistence": [
|
|
"Container volumes"
|
|
],
|
|
"dependencies": [
|
|
"Docker",
|
|
"NVIDIA Container Toolkit"
|
|
],
|
|
"tests": [
|
|
"scripts/check-docker-gpu.sh"
|
|
],
|
|
"documentation": [
|
|
"docs/setup.md"
|
|
],
|
|
"risks": [
|
|
"Driver version incompatibility with host NVIDIA/AMD kernel drivers."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "Dockerfile",
|
|
"symbol": "multi-stage-build",
|
|
"line_range": "L1-L113",
|
|
"explanation": "Multi-stage container build environment."
|
|
},
|
|
{
|
|
"path": "docker-compose.gpu-nvidia.yml",
|
|
"symbol": "nvidia-gpu-manifest",
|
|
"line_range": "L1-L179",
|
|
"explanation": "NVIDIA GPU pass-through container specification."
|
|
},
|
|
{
|
|
"path": "scripts/check-docker-gpu.sh",
|
|
"symbol": "check-docker-gpu",
|
|
"line_range": "L1-L615",
|
|
"explanation": "Automated diagnostic test script for host NVIDIA GPU passthrough."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": true,
|
|
"status": "pending",
|
|
"reason": "Requires Docker GPU pass-through and compatible host drivers."
|
|
}
|
|
},
|
|
{
|
|
"id": "PLATFORM-010",
|
|
"domain": "platform",
|
|
"name": "Legacy FAISS Vector Index Migration Script",
|
|
"purpose": "Legacy utility script to migrate older FAISS vector indices into ChromaDB.",
|
|
"status": "legacy",
|
|
"frontend_entrypoints": [
|
|
"None"
|
|
],
|
|
"backend_entrypoints": [
|
|
"scripts/migrate_faiss_to_chroma.py"
|
|
],
|
|
"routes": [
|
|
"CLI Script"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"Legacy FAISS index files"
|
|
],
|
|
"dependencies": [
|
|
"faiss",
|
|
"chromadb"
|
|
],
|
|
"tests": [
|
|
"tests/helpers/import_state.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Fails if legacy FAISS index files do not exist."
|
|
],
|
|
"unknowns": [
|
|
"Superseded by native ChromaDB vector index pipeline."
|
|
],
|
|
"evidence": [
|
|
{
|
|
"path": "scripts/migrate_faiss_to_chroma.py",
|
|
"symbol": "migrate_faiss",
|
|
"line_range": "L15-L80",
|
|
"explanation": "Reads FAISS vector index files and writes to ChromaDB collection."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "NOTE-001",
|
|
"domain": "note",
|
|
"name": "Interactive Notes & Checklist Management",
|
|
"purpose": "Provides Google Keep-style notes, rich markdown text, checklist items, pinning, color tags, and reminders.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/notes.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/note/note_routes.py:setup_note_routes",
|
|
"src/tools/notes.py"
|
|
],
|
|
"routes": [
|
|
"/api/notes",
|
|
"/api/notes/{note_id}",
|
|
"/api/notes/{note_id}/pin",
|
|
"/api/notes/reorder"
|
|
],
|
|
"configuration": [],
|
|
"persistence": [
|
|
"DATA_DIR/notes.db"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3",
|
|
"pydantic"
|
|
],
|
|
"tests": [
|
|
"tests/test_notes_fail_closed_auth.py",
|
|
"tests/test_manage_notes_owner_gate.py"
|
|
],
|
|
"documentation": [
|
|
"docs/notes.webm"
|
|
],
|
|
"risks": [
|
|
"Concurrent edits on note item checkboxes."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/note/note_routes.py",
|
|
"symbol": "@router.get('')",
|
|
"line_range": "L623-L650",
|
|
"explanation": "Lists all user notes with pin and archive states."
|
|
},
|
|
{
|
|
"path": "static/js/notes.js",
|
|
"symbol": "initNotesView",
|
|
"line_range": "L1-L160",
|
|
"explanation": "Main interactive notes grid and modal manager."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "SKILL-001",
|
|
"domain": "skill",
|
|
"name": "Dynamic Skill Management & Code Execution Engine",
|
|
"purpose": "Allows users to create, import, edit, test, and execute custom Python/Markdown skills dynamically.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/skills.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/skills_routes.py:setup_skills_routes",
|
|
"services/memory/skills.py:SkillsManager"
|
|
],
|
|
"routes": [
|
|
"/api/skills",
|
|
"/api/skills/{skill_id}/invoke",
|
|
"/api/skills/import-from-url"
|
|
],
|
|
"configuration": [
|
|
"SKILLS_DIR"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/skills/"
|
|
],
|
|
"dependencies": [
|
|
"pydantic",
|
|
"httpx"
|
|
],
|
|
"tests": [
|
|
"tests/test_skills_routes_owner_update.py",
|
|
"tests/test_skill_importer.py",
|
|
"tests/test_skill_save_no_rename.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"Arbitrary code execution risks if skill import URL is untrusted."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/skills_routes.py",
|
|
"symbol": "setup_skills_routes",
|
|
"line_range": "L100-L300",
|
|
"explanation": "Exposes CRUD and remote import routes for user skills."
|
|
},
|
|
{
|
|
"path": "services/memory/skills.py",
|
|
"symbol": "SkillsManager",
|
|
"line_range": "L40-L220",
|
|
"explanation": "Handles skill storage, parsing, and execution."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "CONTACT-001",
|
|
"domain": "contact",
|
|
"name": "CardDAV Contact Management & Address Book Integration",
|
|
"purpose": "Connects to CardDAV servers, imports VCard contacts, and provides contact lookup for email/calendar autocomplete.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/emailLibrary.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/contacts/contacts_routes.py:setup_contacts_routes",
|
|
"src/tools/contacts.py"
|
|
],
|
|
"routes": [
|
|
"/api/contacts/list",
|
|
"/api/contacts/search",
|
|
"/api/contacts/add",
|
|
"/api/contacts/config"
|
|
],
|
|
"configuration": [
|
|
"CARDDAV_URL"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/contacts.db"
|
|
],
|
|
"dependencies": [
|
|
"vobject",
|
|
"sqlite3"
|
|
],
|
|
"tests": [
|
|
"tests/test_contacts_carddav_security.py",
|
|
"tests/cli/test_contacts_cli_rows.py"
|
|
],
|
|
"documentation": [
|
|
"README.md"
|
|
],
|
|
"risks": [
|
|
"VCard 3.0 vs 4.0 property parsing mismatches."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/contacts/contacts_routes.py",
|
|
"symbol": "@router.get('/list')",
|
|
"line_range": "L741-L764",
|
|
"explanation": "Returns contact list filtered by search query."
|
|
},
|
|
{
|
|
"path": "src/tools/contacts.py",
|
|
"symbol": "ContactsTool",
|
|
"line_range": "L20-L110",
|
|
"explanation": "Agent tool for querying user address book contacts."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
},
|
|
{
|
|
"id": "MEMORY-001",
|
|
"domain": "memory",
|
|
"name": "Persistent Long-Term Memory & Vector Indexing",
|
|
"purpose": "Extracts facts, user preferences, and temporal memories from chat sessions into vector/relational storage.",
|
|
"status": "verified",
|
|
"frontend_entrypoints": [
|
|
"static/js/memory.js"
|
|
],
|
|
"backend_entrypoints": [
|
|
"routes/memory/memory_routes.py:setup_memory_routes",
|
|
"services/memory/service.py",
|
|
"mcp_servers/memory_server.py"
|
|
],
|
|
"routes": [
|
|
"/api/memory",
|
|
"/api/memory/search",
|
|
"/api/memory/extract",
|
|
"/api/memory/audit"
|
|
],
|
|
"configuration": [
|
|
"MEMORY_AUTO_EXTRACT"
|
|
],
|
|
"persistence": [
|
|
"DATA_DIR/memory.db",
|
|
"DATA_DIR/memory_chroma/"
|
|
],
|
|
"dependencies": [
|
|
"sqlite3",
|
|
"chromadb"
|
|
],
|
|
"tests": [
|
|
"tests/test_memory_routes_session_owner.py",
|
|
"tests/test_consolidate_memory_explicit_drops.py"
|
|
],
|
|
"documentation": [
|
|
"docs/theme.webm"
|
|
],
|
|
"risks": [
|
|
"Conflicting memory facts extracted from contradictory user prompts."
|
|
],
|
|
"unknowns": [],
|
|
"evidence": [
|
|
{
|
|
"path": "routes/memory/memory_routes.py",
|
|
"symbol": "@router.get('')",
|
|
"line_range": "L132-L150",
|
|
"explanation": "Fetches long-term user memory timeline."
|
|
},
|
|
{
|
|
"path": "services/memory/memory_extractor.py",
|
|
"symbol": "MemoryExtractor",
|
|
"line_range": "L30-L160",
|
|
"explanation": "LLM-driven fact extraction from conversation transcripts."
|
|
}
|
|
],
|
|
"verified_at_commit": "d8a2059df8e53bc7275c45339849d14c8651e73c",
|
|
"evidence_maturity": "E0",
|
|
"runtime_validation": {
|
|
"required": false,
|
|
"status": "not-required",
|
|
"reason": "No separate environment-dependent runtime validation was identified during this documentation pass."
|
|
}
|
|
}
|
|
]
|