Skip to content

Architecture Validation: 6 critical violations found (2026-04-27) #528

Description

@vybe

Automated Architecture Validation Report

Date: 2026-04-27
Result: 6 critical violations requiring attention (10/16 PASS, 6/16 FAIL)

Critical Findings (P0-P1)

#1 Three-Layer Backend: Router → Service → DB (FAIL)

SQL executed directly in router files — violates the Router → Service → DB separation:

  • routers/voice.py:176,304 — direct cursor.execute() with UPDATE/SELECT SQL
  • routers/git.py:298 — direct db.execute_query("DELETE FROM agent_git_config ...")
  • routers/processes.py:781,819,865 — direct cursor.execute() with CREATE TABLE, INSERT, DELETE
  • routers/triggers.py:254 — direct cursor.execute() with SELECT

#3 Schema in db/schema.py, Migrations in db/migrations.py (FAIL)

CREATE TABLE statements found outside the canonical schema/migration files:

  • routers/processes.py:781CREATE TABLE IF NOT EXISTS process_schedules
  • services/process_engine/services/templates.py:117CREATE TABLE IF NOT EXISTS process_templates
  • services/process_engine/services/alerts.py:163,178CREATE TABLE IF NOT EXISTS cost_thresholds, cost_alerts

#13 Credentials: File Injection, Never Stored in DB (FAIL — CRITICAL)

Slack bot tokens stored in plaintext in SQLite — violates the no-credentials-in-DB rule:

  • db/schema.py:537slack_link_connections table has slack_bot_token TEXT NOT NULL
  • db/slack.py:38-42 — INSERT writes the plaintext bot token directly
  • db/slack.py:172 — SELECT returns plaintext token in row results

Correct pattern (used by subscriptions and nevermined): AES-256-GCM encryption via CredentialEncryptionService.

#8 Auth Pattern: Missing Protection (FAIL — Partial)

  • routers/docs.py — endpoints have no auth dependency, publicly accessible
  • routers/executions.py:19-27, routers/processes.py, routers/process_templates.py — import directly from process_engine.domain (bypassing service layer)

Non-Critical Findings (P2-P3 — informational)

#6 Frontend Store = Domain, View = Page (FAIL)

  • ProcessEditor.vue, ProcessList.vue, ProcessWizard.vue — 8 direct api.get()/api.post() calls; views import API client directly instead of going through stores.

#10 Process Engine DDD Isolation (FAIL)

  • routers/executions.py, routers/processes.py, routers/process_templates.py — import directly from process_engine.domain instead of going through services.

#11 WebSocket Events for Real-Time (FAIL)

  • views/ExecutionDetail.vuesetInterval polling instead of WebSocket for execution status
  • stores/notifications.js:226setInterval polling for notification count
  • stores/monitoring.jssetInterval polling for fleet status

#15 Pydantic Models Centralized in models.py (FAIL)

  • 10+ router files define inline BaseModel subclasses (e.g., event_subscriptions.py:359, agent_files.py)

#16 API URL Nesting Convention (FAIL)

  • event_subscriptions.py:295,334,365 — agent-scoped resources at /api/event-subscriptions/{id}, /api/events (not nested under /api/agents/{name}/)
  • notifications.py:70,120,177,193 — agent-scoped resources at /api/notifications/...

Recommended Actions (Priority Order)

  1. [P0] Encrypt Slack bot tokens — Apply CredentialEncryptionService.encrypt() before writing to slack_link_connections.slack_bot_token; add migration to re-encrypt existing rows.
  2. [P1] Move ad-hoc CREATE TABLE to schema.py/migrations.py — Tables: process_schedules, process_templates, cost_thresholds, cost_alerts.
  3. [P1] Move SQL out of routersvoice.py, git.py, processes.py, triggers.py need service/db layer extraction.
  4. [P2] Add auth to docs.py or document why it should remain public.
  5. [P2] Move process engine domain imports behind service layer in routers/executions.py, routers/processes.py, routers/process_templates.py.
  6. [P3] Migrate polling to WebSocket in ExecutionDetail, notifications, monitoring.
  7. [P3] Move inline Pydantic models from router files to models.py.
  8. [P3] Fix URL nesting for event subscriptions and notifications.

Generated by scheduled /validate-architecture run on 2026-04-27

Metadata

Metadata

Assignees

No one assigned

    Labels

    automatedAutomatically generated by scheduled taskscomplexity-lowComplexity: low (board points 1-3)priority-p1Critical paththeme-devexTheme: DevExtype-bugBug fix

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions