Automated Architecture Validation Report
Date : 2026-04-22
Result : 8/16 invariants FAIL — 4 are P0-P1 critical violations requiring immediate attention
Critical Findings (P0-P1)
#1 — Three-Layer Backend: Router → Service → DB (FAIL)
Routers contain raw SQL, bypassing the service/db layers:
src/backend/routers/git.py:298 — db.execute_query("DELETE FROM agent_git_config ...")
src/backend/routers/processes.py:780 — cursor.execute("CREATE TABLE IF NOT EXISTS process_schedules ...")
src/backend/routers/processes.py:819 — cursor.execute("INSERT OR REPLACE INTO process_schedules ...")
src/backend/routers/processes.py:865 — cursor.execute("DELETE FROM process_schedules ...")
src/backend/routers/triggers.py:254 — cursor.execute("SELECT * FROM process_schedules ...")
#3 — Schema in db/schema.py, Migrations in db/migrations.py (FAIL)
CREATE TABLE statements found outside the canonical schema files:
src/backend/routers/processes.py:780 — CREATE TABLE IF NOT EXISTS process_schedules
src/backend/services/process_engine/services/alerts.py:163 — CREATE TABLE IF NOT EXISTS cost_thresholds
src/backend/services/process_engine/services/alerts.py:178 — CREATE TABLE IF NOT EXISTS cost_alerts
src/backend/services/process_engine/services/templates.py:117 — CREATE TABLE IF NOT EXISTS process_templates
src/backend/services/process_engine/repositories/audit.py:62 — CREATE TABLE IF NOT EXISTS audit_entries
src/backend/services/process_engine/repositories/sqlite_definitions.py:70 — CREATE TABLE IF NOT EXISTS process_definitions
src/backend/services/process_engine/repositories/sqlite_executions.py — process_executions and step_executions tables
src/backend/services/process_engine/repositories/sqlite_events.py — CREATE TABLE IF NOT EXISTS execution_events
#8 — Auth Pattern: Depends(get_current_user) (FAIL)
src/backend/routers/docs.py exposes routes with no authentication:
Line 33: @router.get("/index") — no auth dependency
Line 51: @router.get("/content/{slug:path}") — no auth dependency
Line 102: @router.get("/list") — no auth dependency
These serve process documentation and should require at least get_current_user unless intentionally public.
#13 — Credentials: Never Stored in DB (FAIL)
src/backend/db/schema.py:271 — slack_bot_token TEXT NOT NULL in slack_link_connections table stores a bot token as plain text. The architecture doc describes "encrypted bot tokens" in the adapters layer; verify whether the value stored is actually encrypted at the application layer before write.
Non-Critical Failures (P2-P3, track separately)
#6 — Frontend Store = Domain, View = Page (FAIL)
ProcessWizard.vue, ProcessList.vue, ProcessEditor.vue import api.js directly and call api.get()/api.post() instead of going through stores.
#7 — Single API Client (FAIL)
20+ raw fetch() calls found in views (AgentDetail.vue, Approvals.vue, ApiKeys.vue, PublicChat.vue, FileManager.vue, etc.) — these bypass the centralized Axios client and its auth interceptors.
#10 — Process Engine DDD Isolation (FAIL)
10 direct imports of process_engine.domain found in routers (approvals.py, triggers.py, processes.py, executions.py, process_templates.py). Routers should go through process engine services, not domain classes directly.
#15 — Pydantic Models Centralized (FAIL)
87 BaseModel subclasses found scattered across router files vs 26 in models.py. Models should live in models.py to keep the API contract in one place.
Passing Invariants (8/16)
✅ #2 DB Mixin Composition | ✅ #4 Router Registration Order | ✅ #5 Agent Server Mirrors Backend
✅ #9 Channel Adapter ABC | ✅ #11 WebSocket Events | ✅ #12 Docker as Source of Truth
✅ #14 MCP Server Third Surface | ✅ #16 API URL Nesting Convention
Recommended Actions
Fix: Add missing Docker labels to system agent container #1 + Feature/vector log retention #3 : Move process_schedules DDL to db/schema.py/db/migrations.py; extract SQL from processes.py and triggers.py into a db operations class. Move Process Engine CREATE TABLE from repository/service files to the canonical schema.
security: implement safe tar extraction with symlink/hardlink validation #8 : Add Depends(get_current_user) to docs.py endpoints or explicitly mark them as intentionally public with a comment explaining why.
feat: SMARTS trading pipeline with Telegram notifications and Miro visualization #13 : Verify whether slack_bot_token is encrypted at the application layer before storage; if not, encrypt it.
Feature/process engine #6 /security: Fix token logging and add HTML reports to gitignore #7 : Migrate direct api.js imports and raw fetch() calls in views to use stores/composables.
Feature/process engine #10 : Refactor process engine router imports to go through service layer, not domain layer directly.
Security: Agent Credential Leakage in Execution Logs [FIXED] #15 : Migrate router-local BaseModel classes to models.py.
Generated by scheduled /validate-architecture run on 2026-04-22
Automated Architecture Validation Report
Date: 2026-04-22
Result: 8/16 invariants FAIL — 4 are P0-P1 critical violations requiring immediate attention
Critical Findings (P0-P1)
#1 — Three-Layer Backend: Router → Service → DB (FAIL)
Routers contain raw SQL, bypassing the service/db layers:
src/backend/routers/git.py:298—db.execute_query("DELETE FROM agent_git_config ...")src/backend/routers/processes.py:780—cursor.execute("CREATE TABLE IF NOT EXISTS process_schedules ...")src/backend/routers/processes.py:819—cursor.execute("INSERT OR REPLACE INTO process_schedules ...")src/backend/routers/processes.py:865—cursor.execute("DELETE FROM process_schedules ...")src/backend/routers/triggers.py:254—cursor.execute("SELECT * FROM process_schedules ...")#3 — Schema in
db/schema.py, Migrations indb/migrations.py(FAIL)CREATE TABLEstatements found outside the canonical schema files:src/backend/routers/processes.py:780—CREATE TABLE IF NOT EXISTS process_schedulessrc/backend/services/process_engine/services/alerts.py:163—CREATE TABLE IF NOT EXISTS cost_thresholdssrc/backend/services/process_engine/services/alerts.py:178—CREATE TABLE IF NOT EXISTS cost_alertssrc/backend/services/process_engine/services/templates.py:117—CREATE TABLE IF NOT EXISTS process_templatessrc/backend/services/process_engine/repositories/audit.py:62—CREATE TABLE IF NOT EXISTS audit_entriessrc/backend/services/process_engine/repositories/sqlite_definitions.py:70—CREATE TABLE IF NOT EXISTS process_definitionssrc/backend/services/process_engine/repositories/sqlite_executions.py— process_executions and step_executions tablessrc/backend/services/process_engine/repositories/sqlite_events.py—CREATE TABLE IF NOT EXISTS execution_events#8 — Auth Pattern:
Depends(get_current_user)(FAIL)src/backend/routers/docs.pyexposes routes with no authentication:@router.get("/index")— no auth dependency@router.get("/content/{slug:path}")— no auth dependency@router.get("/list")— no auth dependencyThese serve process documentation and should require at least
get_current_userunless intentionally public.#13 — Credentials: Never Stored in DB (FAIL)
src/backend/db/schema.py:271—slack_bot_token TEXT NOT NULLinslack_link_connectionstable stores a bot token as plain text. The architecture doc describes "encrypted bot tokens" in the adapters layer; verify whether the value stored is actually encrypted at the application layer before write.Non-Critical Failures (P2-P3, track separately)
#6 — Frontend Store = Domain, View = Page (FAIL)
ProcessWizard.vue,ProcessList.vue,ProcessEditor.vueimportapi.jsdirectly and callapi.get()/api.post()instead of going through stores.#7 — Single API Client (FAIL)
20+ raw
fetch()calls found in views (AgentDetail.vue,Approvals.vue,ApiKeys.vue,PublicChat.vue,FileManager.vue, etc.) — these bypass the centralized Axios client and its auth interceptors.#10 — Process Engine DDD Isolation (FAIL)
10 direct imports of
process_engine.domainfound in routers (approvals.py,triggers.py,processes.py,executions.py,process_templates.py). Routers should go through process engine services, not domain classes directly.#15 — Pydantic Models Centralized (FAIL)
87
BaseModelsubclasses found scattered across router files vs 26 inmodels.py. Models should live inmodels.pyto keep the API contract in one place.Passing Invariants (8/16)
✅ #2 DB Mixin Composition | ✅ #4 Router Registration Order | ✅ #5 Agent Server Mirrors Backend
✅ #9 Channel Adapter ABC | ✅ #11 WebSocket Events | ✅ #12 Docker as Source of Truth
✅ #14 MCP Server Third Surface | ✅ #16 API URL Nesting Convention
Recommended Actions
process_schedulesDDL todb/schema.py/db/migrations.py; extract SQL fromprocesses.pyandtriggers.pyinto a db operations class. Move Process EngineCREATE TABLEfrom repository/service files to the canonical schema.Depends(get_current_user)todocs.pyendpoints or explicitly mark them as intentionally public with a comment explaining why.slack_bot_tokenis encrypted at the application layer before storage; if not, encrypt it.api.jsimports and rawfetch()calls in views to use stores/composables.BaseModelclasses tomodels.py.Generated by scheduled
/validate-architecturerun on 2026-04-22