refactor(layout): fold the prefix-shared AI files into their own folders

test_prefix_groups_belong_in_subfolders flagged three groups added by this change
set: a shared delimiter-bounded prefix is a folder in disguise, so the group moves
into a folder named after the prefix and the prefix leaves the file names.

  sql/select/ai-{bot-user,service}.sql.j2  -> sql/select/ai/{bot-user,service}.sql.j2
  files/provision_{ai,mcp}.py              -> files/provision/{ai,mcp}.py
  files/ai_engine_{configure,endpoint}.php -> files/ai_engine/{configure,endpoint}.php

All six are recorded as renames, so history follows them. Every reference moves
with them: four templated query paths in mattermost's ai_gateway.yml, the two
lookup('file', ...) calls in n8n, the two in wordpress, and SCRIPT_PATH plus the
module docstring in the n8n unit test. lookup('file', ...) resolves relative to
the role's files/ directory, so the new argument is provision/mcp.py rather than
a repo-relative path.

Worth recording why this survived every gate: make quality was green on each run
this session, including immediately before the commits that introduced these
files. The lint enumerates through git ls-files, and the files were untracked, so
it could not see them. Committing them is what made them visible. A green gate
taken before new files are tracked says nothing about the gate after.

Verified: repository lints go from 88 passed with 1 failure to 89 passed, the
unit suite passes at 4448, and a repo-wide grep for every old path returns
nothing.
Not verified: no deploy has run. The lookup('file', ...) arguments and the
templated SQL paths resolve at play time, so a wrong path would surface as a task
failure rather than a test failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-08-24 15:19:26 +02:00
1 parent 507e3f4337
commit 8e8dbbd08c
11 files changed
+10 -10

No files matched your search

@@ -20,7 +20,7 @@
- name: "🔎 Mattermost | Compare the stored Agents config to the contract"
database_query:
config: "{{ lookup('database', application_id) }}"
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai-service.sql.j2') }}" # nocheck: database-query-raw the desired service and bot are rendered from role vars
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai/service.sql.j2') }}" # nocheck: database-query-raw the desired service and bot are rendered from role vars
expect_rows: true
mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
register: mattermost_ai_state
@@ -34,7 +34,7 @@
- name: "🔎 Mattermost | Count the Agents bot accounts the plugin has provisioned"
database_query:
config: "{{ lookup('database', application_id) }}"
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai-bot-user.sql.j2') }}" # nocheck: database-query-raw the bot username is templated into the predicate
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai/bot-user.sql.j2') }}" # nocheck: database-query-raw the bot username is templated into the predicate
expect_rows: true
register: mattermost_ai_bot_state
changed_when: false
@@ -63,7 +63,7 @@
- name: "🔎 Mattermost | Re-read the stored Agents service and bot"
database_query:
config: "{{ lookup('database', application_id) }}"
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai-service.sql.j2') }}" # nocheck: database-query-raw the desired service and bot are rendered from role vars
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai/service.sql.j2') }}" # nocheck: database-query-raw the desired service and bot are rendered from role vars
expect_rows: true
mask_values: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
register: mattermost_ai_state_final
@@ -84,7 +84,7 @@
- name: "🔎 Mattermost | Wait for the Agents plugin to provision its bot account"
database_query:
config: "{{ lookup('database', application_id) }}"
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai-bot-user.sql.j2') }}" # nocheck: database-query-raw the bot username is templated into the predicate
query: "{{ lookup('template', role_path ~ '/templates/sql/select/ai/bot-user.sql.j2') }}" # nocheck: database-query-raw the bot username is templated into the predicate
expect_rows: true
register: mattermost_ai_bot_final
retries: 60
+1 -1
View File
@@ -7,7 +7,7 @@
argv:
- python3
- "-"
stdin: "{{ lookup('file', 'provision_ai.py') }}"
stdin: "{{ lookup('file', 'provision/ai.py') }}"
environment:
N8N_BASE: "{{ N8N_INTERNAL_API_URL }}"
N8N_OWNER_EMAIL: "{{ N8N_OWNER_EMAIL }}"
+1 -1
View File
@@ -4,7 +4,7 @@
argv:
- python3
- "-"
stdin: "{{ lookup('file', 'provision_mcp.py') }}"
stdin: "{{ lookup('file', 'provision/mcp.py') }}"
environment:
N8N_BASE: "{{ N8N_INTERNAL_API_URL }}"
N8N_OWNER_EMAIL: "{{ N8N_OWNER_EMAIL }}"
@@ -17,7 +17,7 @@
- eval-file
- "-"
- "--path={{ WORDPRESS_DOCKER_HTML_PATH }}"
stdin: "{{ lookup('file', 'ai_engine_configure.php') }}"
stdin: "{{ lookup('file', 'ai_engine/configure.php') }}"
changed_when: true
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
@@ -36,7 +36,7 @@
- eval-file
- "-"
- "--path={{ WORDPRESS_DOCKER_HTML_PATH }}"
stdin: "{{ lookup('file', 'ai_engine_endpoint.php') }}"
stdin: "{{ lookup('file', 'ai_engine/endpoint.php') }}"
register: wordpress_ai_endpoint
changed_when: false
@@ -1,4 +1,4 @@
"""Unit tests for ``roles/web-app-n8n/files/provision_mcp.py``."""
"""Unit tests for ``roles/web-app-n8n/files/provision/mcp.py``."""
from __future__ import annotations
@@ -8,7 +8,7 @@ from unittest.mock import patch
from . import PROJECT_ROOT
SCRIPT_PATH = PROJECT_ROOT / "roles/web-app-n8n/files/provision_mcp.py"
SCRIPT_PATH = PROJECT_ROOT / "roles/web-app-n8n/files/provision/mcp.py"
ENV = {
"N8N_BASE": "http://n8n:5678",