Drupal Module Decision Matrix¶
Authority: Thomas, 2026-09-25
Evidence source: ddev exec drush pm:list on contextcontrol-ai, 2026-09-25T20:10Z + upstream Drupal.org release pages
Living Plan ref: §24 — Drupal Engineering Pack and Upstream Module Decisions
Binding Decisions¶
AI_SEARCH=DO_NOT_ADD_AS_NEW_DEPENDENCY
Reason: Deprecated in Drupal AI 1.5. Do not add to any recipe, composer.json, or pack.
AI_CKEDITOR=DO_NOT_ADD_AS_NEW_DEPENDENCY
Reason: Deprecated in Drupal AI 1.5.
ECA=DEFAULT_FOR_EVENT_CONDITION_ACTION_WITHIN_DRUPAL
Use ECA for event/condition/action rules. Do not replace with flowdrop for simple rules.
FLOWDROP=PILOT_ONLY_WHERE_TYPED_PORTS_AND_TRACES_GENUINELY_NEEDED
Do not install everywhere. ECA already owns many simpler rules.
CANVAS_AI_MIGRATIONS=EVALUATE_ALONGSIDE_AI_MIGRATION_NOT_REPLACE
No release. No security advisory coverage. Candidate only. Not factory foundation.
AI_MIGRATION_RC1=PILOT_FOR_MIGRATION_FACTORY
Structured field extraction into Drupal via Migrate. RC1 as of 2026-08-15.
MCP_SERVER=REPLACEMENT_FOR_DRUPAL_MCP
Retire drupal/mcp. Adopt mcp_server beta5. Exposes Tool API plugins via config (STDIO + HTTP).
TOOL_API_TOOL_BELT=PILOT_ON_CONTROLLED_RIG
Review every exposed tool's permission and effect before agent access.
AI_CONTEXT_RC1=EVALUATE_VS_KB_CACHE_BEFORE_UPGRADE
RC1 now owns: context entities, moderation, revisions, scope subscriptions, token limits,
usage tracking, agent context selection. Map against kb_cache before deciding.
Module Version Table¶
Verified 2026-09-25 against contextcontrol-ai (live site).
| Module | Installed | Canonical 2026-09-25 | Status | Bead |
|---|---|---|---|---|
canvas |
1.11.0 | 1.12.0 | UPGRADE — brand kit, CLI, stale styles | bc-9o0 |
ai |
1.5.0-rc4 | 1.5.0 stable | UPGRADE when stable | mba-zpdj0 |
ai_agents |
1.3.5 | 1.3.5 stable | ✅ OK | — |
ai_context |
1.0.0-beta4 | 1.0.0-RC1 | EVALUATE first | mba-mnd4f |
eca |
2.1.24 | 3.1.9 | BREAKING MIGRATION — plan before upgrade | mba-9wpms |
tool |
1.0.0-beta9 | beta9 | ✅ OK | — |
tool_belt |
1.0.0-alpha5 | alpha5 | ✅ OK | — |
mcp |
1.2.3 | — (retiring) | MIGRATE → mcp_server | mba-3lyul |
mcp_tools |
1.0.0-beta8 | beta8 | ✅ OK | — |
mcp_server |
not installed | beta5 | TARGET of mcp migration | mba-3lyul |
ai_search |
1.3.0-alpha4 | deprecated | DO NOT ADD new dep | — |
flowdrop |
not enabled | 2.6.0 stable | PILOT only | — |
ai_assistant_api |
1.5.0-rc4 | stable | upgrade with ai | mba-zpdj0 |
ai_automators |
1.5.0-rc4 | stable | upgrade with ai | mba-zpdj0 |
ai_observability |
1.5.0-rc4 | stable | upgrade with ai | mba-zpdj0 |
Pack Architecture Decision¶
Do not create a separate drupal-engineering pack.
BluCity-Packs already has a drupal/* pack family:
drupal/core drupal/ai drupal/content
drupal/workflows drupal/search drupal/migration
drupal/recipes drupal/seo drupal/accessibility
New formulas and orders go into the correct sub-pack.
Bead: mba-t0oc1
drupal-change Formula v2 Shape¶
Belongs in drupal/core pack. Step needs chain enforces order:
formula = "drupal-change"
description = "Deliver a verified Drupal change in a registered rig"
[requires]
formula_compiler = ">=2.0.0"
[vars.request]
description = "Bead or precise change request"
required = true
[[steps]]
id = "inventory"
title = "Establish Drupal and rig state for {{request}}"
description = """Read the request, repository instructions, Composer lock, enabled modules,
recipe sources, config splits, DDEV state, and relevant upstream projects.
Record what was actually observed."""
[[steps]]
id = "design"
title = "Select the upstream owner for {{request}}"
needs = ["inventory"]
description = """Choose core, contrib, configuration, recipe, Canvas/SDC, ECA/FlowDrop,
Drupal AI, or an existing extension.
Record the gap before proposing custom code."""
[[steps]]
id = "implement"
title = "Implement {{request}} in the correct repository"
needs = ["design"]
description = """Use an isolated branch/worktree. Keep Drupal source in DrupalWorks.
Do not run a blanket config export on a config-split site; export only reviewed objects."""
[[steps]]
id = "verify"
title = "Verify the user-visible effect of {{request}}"
needs = ["implement"]
description = """Run relevant DDEV checks, inspect config and code diff, test the actual
site behavior, and record commands, results, and limitations."""
[[steps]]
id = "witness"
title = "Independently review {{request}}"
needs = ["verify"]
description = """Check the upstream choice, unnecessary custom code, security, config split,
evidence, and acceptance criteria. Return defects as work, not prose approval."""
[[steps]]
id = "deliver"
title = "Deliver {{request}} through GitLab"
needs = ["witness"]
description = """Prepare the MR with the evidence and exact scope.
Confirm CI result and final repository state before reporting completion."""
Three Workflows to Prove (Sequential)¶
W1: Site change → W2 and W3 blocked on W1 receipt
W2: Contrib watch
W3: Migration pilot
W1 — Site Change¶
Request → upstream-first selection → recipe/config or justified code
→ DDEV behavior check → Witness → GitLab MR
W2 — Contrib Watch¶
Read current lockfiles → compare Drupal.org releases and advisories
→ open beads only for actionable changes → test on one rig → MR
Watchlist: canvas, ai, ai_agents, ai_context, eca, flowdrop, tool, tool_belt, mcp_server
Order: manual trigger first; weekly cron only after receipt proves useful
W3 — Migration Pilot¶
Inventory source URLs and content types
→ define Drupal fields/templates
→ AI Migration (structured extraction)
→ Canvas tooling (visual reconstruction)
→ compare screenshots + accessibility
→ publish new item through Drupal (proves editorial sustainability)
→ record cost, time, failures
Acceptance test: create a new article/event through Drupal after migration, renders without re-running agent.
Receipt Requirements for Drupal Factory Work¶
Every receipt must include: - rig name, DDEV state, Drupal version - module versions affected (before → after) - exact test command and observed output - actual site behavior (not assertion) - Witness finding (PASS / FAIL / PARTIAL) - any unresolved limitation with a linked bead
exit 0 while reporting unavailable store or unknown agents = DEGRADED, not SUCCESS
Hard timeouts required on all live site checks.
Updated: 2026-09-25. Next review trigger: Drupal AI 1.5.0 stable lands or ECA 3.x migration completes.