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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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