chore: add GRACE semantic contracts across agent + backend + build scripts

- Add @RELATION/@RATIONALE/@REJECTED headers to agent modules
- Add GRACE contracts to backend services, models, schemas
- Update build.sh with single-image build commands (build:backend|frontend|agent)
- Update docker entrypoint: openssl rsa → openssl pkey (alg-agnostic)
- Add @RATIONALE to backend core modules (cot_logger, config_manager, ssl)
This commit is contained in:
2026-07-08 11:10:59 +03:00
parent b6b1e05567
commit f22b0cf41c
34 changed files with 452 additions and 263 deletions

View File

@@ -2,4 +2,17 @@
# #region AgentChat [C:3] [TYPE Module] [SEMANTICS agent-chat]
# @defgroup AgentChat LangGraph-based Gradio agent — streaming chat with HITL guardrails.
# @LAYER Application
# @RELATION DISPATCHES -> [AgentChat.Config]
# @RELATION DISPATCHES -> [AgentChat.Tools]
# @RELATION DISPATCHES -> [AgentChat.Confirmation]
# @RELATION DISPATCHES -> [AgentChat.Context]
# @RELATION DISPATCHES -> [AgentChat.Context.Validate]
# @RELATION DISPATCHES -> [AgentChat.LangGraph.Setup]
# @RELATION DISPATCHES -> [AgentChat.ToolResolver]
# @RELATION DISPATCHES -> [AgentChat.ToolFilter]
# @RELATION DISPATCHES -> [AgentChat.LlmParams]
# @RELATION DISPATCHES -> [AgentChat.Middleware]
# @RELATION DISPATCHES -> [AgentChat.Persistence]
# @RELATION DISPATCHES -> [AgentChat.Document.Parser]
# @RELATION DISPATCHES -> [AgentChat.GradioApp]
# #endregion AgentChat

View File

@@ -4,6 +4,8 @@
# @LAYER Service
# @RELATION DEPENDS_ON -> [AgentChat.ToolResolver]
# @RELATION DEPENDS_ON -> [AgentChat.Tools]
# @RELATION DEPENDS_ON -> [AgentChat.LlmParams]
# @RELATION DEPENDS_ON -> [AgentChat.LangGraph.Setup]
# @RATIONALE Extracting confirmation logic into a dedicated module prevents the handler
# from exceeding 400 lines and centralises risk classification in one place.
from collections.abc import AsyncGenerator

View File

@@ -1,5 +1,6 @@
# agent/src/ss_tools/agent/_context.py
# #region AgentChat.Context.Validate [C:3] [TYPE Module] [SEMANTICS agent-chat,context,validate,security]
# @ingroup AgentChat
# @BRIEF UIContext validation and prompt-injection protection.
# @LAYER Service
# @POST Passes through contextVersion, objectType, objectId, objectName, envId, route, padding.

View File

@@ -1,5 +1,6 @@
# agent/src/ss_tools/agent/_llm_params.py
# #region AgentChat.LlmParams [C:3] [TYPE Module] [SEMANTICS agent-chat,llm,openai,compatibility]
# @ingroup AgentChat
# @BRIEF Build provider-safe ChatOpenAI kwargs and raw OpenAI payloads.
# @POST Unsupported sampling parameters are omitted for reasoning/codex models.
from typing import Any

View File

@@ -1,7 +1,11 @@
# agent/src/ss_tools/agent/_persistence.py
# #region AgentChat.Persistence [C:3] [TYPE Module] [SEMANTICS agent-chat,persistence,save,prefetch,title]
# @ingroup AgentChat
# @BRIEF Conversation persistence helpers — save, clean titles, LLM title generation, prefetch.
# @LAYER Service
# @RELATION DEPENDS_ON -> [AgentChat.Config]
# @RELATION DEPENDS_ON -> [AgentChat.LlmParams]
# @RELATION DEPENDS_ON -> [AgentChat.Tools]
import asyncio
from datetime import datetime

View File

@@ -1,5 +1,6 @@
# agent/src/ss_tools/agent/_tool_filter.py
# #region AgentChat.ToolFilter [C:3] [TYPE Module] [SEMANTICS agent-chat,tools,filter,context]
# @ingroup AgentChat
# @BRIEF Context-aware tool filtering + RBAC enforcement.
# @LAYER Service
# @DATA_CONTRACT build_tool_pipeline returns a list — never mutates the input list.

View File

@@ -1,6 +1,8 @@
# agent/src/ss_tools/agent/_tool_resolver.py
# #region AgentChat.ToolResolver [C:2] [TYPE Module] [SEMANTICS agent-chat,tools,resolution]
# @ingroup AgentChat
# @BRIEF Tool resolution helpers for the LangGraph agent.
# @RELATION DEPENDS_ON -> [AgentChat.Tools]
# @LAYER Service
from typing import Any

View File

@@ -9,6 +9,9 @@
# @RELATION DEPENDS_ON -> [AgentChat.Confirmation]
# @RELATION DEPENDS_ON -> [AgentChat.Persistence]
# @RELATION DEPENDS_ON -> [AgentChat.LangGraph.Setup]
# @RELATION DEPENDS_ON -> [AgentChat.Config]
# @RELATION DEPENDS_ON -> [AgentChat.Tools]
# @RELATION DEPENDS_ON -> [AgentChat.Context]
# @RATIONALE Gradio ChatInterface chosen for its built-in streaming, file upload, and multimodal support — avoids custom WebSocket implementation for agent chat.
# @REJECTED Custom React chat frontend rejected — Gradio provides free authentication, session management, and mobile-responsive UI out of the box.

View File

@@ -1,5 +1,6 @@
# agent/src/ss_tools/agent/context.py
# #region AgentChat.Context [C:3] [TYPE Module] [SEMANTICS agent-chat,context,auth]
# @ingroup AgentChat
# @BRIEF JWT context propagation for LangGraph tools.
# @RATIONALE LangGraph tool execution may run in a different async context,
# preventing ContextVar from propagating. Module-level globals

View File

@@ -1,5 +1,6 @@
# agent/src/ss_tools/agent/document_parser.py
# #region AgentChat.Document.Parser [C:3] [TYPE Module] [SEMANTICS agent-chat,document,parser]
# @ingroup AgentChat
# @BRIEF Parse PDF and XLSX files into text/structured data.
# @RELATION DEPENDS_ON -> [EXT:pdfplumber]
# @RELATION DEPENDS_ON -> [EXT:openpyxl]

View File

@@ -1,8 +1,11 @@
# agent/src/ss_tools/agent/langgraph_setup.py
# #region AgentChat.LangGraph.Setup [C:4] [TYPE Module] [SEMANTICS agent-chat,langgraph,agent]
# @ingroup AgentChat
# @BRIEF LangGraph agent setup: create_react_agent with PostgresSaver.
# @PRE LLM provider configured via backend API /api/agent/llm-config.
# @POST Compiled StateGraph ready for astream_events().
# @RELATION DEPENDS_ON -> [AgentChat.Config]
# @RELATION DEPENDS_ON -> [AgentChat.LlmParams]
import inspect as _inspect
import os

View File

@@ -1,6 +1,9 @@
# agent/src/ss_tools/agent/middleware.py
# #region AgentChat.Middleware [C:3] [TYPE Module] [SEMANTICS agent-chat,middleware,logging,audit]
# @ingroup AgentChat
# @BRIEF Audit logging middleware for the LangGraph agent.
# @RELATION DEPENDS_ON -> [AgentChat.Context]
# @RELATION DEPENDS_ON -> [AgentChat.Tools]
from datetime import UTC, datetime
from ss_tools.agent.context import get_user_jwt

View File

@@ -1,6 +1,8 @@
# agent/src/ss_tools/agent/tools.py
# #region AgentChat.Tools [C:4] [TYPE Module] [SEMANTICS agent-chat,tools,langchain]
# @defgroup AgentChat Native LangChain @tool functions.
# @RELATION DEPENDS_ON -> [AgentChat.Config]
# @RELATION DEPENDS_ON -> [AgentChat.Context]
# @RATIONALE LangChain @tool decorator chosen over direct FastAPI calls for LangGraph compatibility — tools are auto-registered in the agent's tool-calling loop.
# @REJECTED StructuredTool wrapping — native @tool is the single source of truth.
# @INVARIANT Every @tool function MUST have a Python docstring (triple-quoted string immediately after the signature). LangChain raises ValueError("Function must have a docstring if description not provided.") when args_schema is provided without a description param AND the function lacks a docstring. This is a runtime blocker — the entire Gradio agent fails to import when ANY single tool violates this invariant. The GRACE @BRIEF comment is NOT a substitute — it's structural metadata invisible to the Python runtime. Rule: BEFORE decorating with @tool(args_schema=...), ensure `"""One-line description."""` is present on the next line.