docs: add CFML Engines page covering Adobe CF and BoxLang setup#2511
docs: add CFML Engines page covering Adobe CF and BoxLang setup#2511
Conversation
The Start Here section pointed every reader at LuCLI without explaining that LuCLI is a Lucee-only convenience and the framework itself runs on Adobe CF 2023/2025 and BoxLang as well. Issue #2494 filed against this gap — Adobe CF / BoxLang users had no documented path from "I want to use Wheels" to "I have a running dev server." Add `start-here/cfml-engines.mdx` with: - A TL;DR matrix (which engine works with which CLI) - An explanation of why the `wheels` CLI is Lucee-only - Two routes for Adobe CF — CommandBox (recommended) and a manual install — with the actual `box server start cfengine=adobe@2025` command line - BoxLang setup via CommandBox - A "Pick an engine" decision section Wire it into `start-here/index.mdx`'s CardGrid (sidebar order 6, after the tutorial) and add a top-of-page tip in `installing.mdx` that points Adobe / BoxLang users at the new page so they aren't silently steered into the Lucee-only flow. Resolves #2494.
| | Adobe ColdFusion 2023 / 2025 | No — install manually | Yes — recommended | Yes | | ||
| | BoxLang | No | Yes | Yes | | ||
|
|
||
| The framework's CI matrix (`.github/workflows/compat-matrix.yml`) runs every release against Lucee 6, Lucee 7, Adobe CF 2023, Adobe CF 2025, and BoxLang on each release. Engine support is hard-gated. |
There was a problem hiding this comment.
🔴 Line 21 makes two factual claims that are contradicted by the workflow it cites: "runs every release ... Engine support is hard-gated" and (later) "BoxLang compatibility is verified per release." compat-matrix.yml is the opposite of both — its own header calls it "Non-blocking — informational only", it triggers only on schedule: cron '0 2 * * 0' and workflow_dispatch (no release/push/PR triggers), and it sets continue-on-error: true with fail-fast: false. The release/PR pipelines (release.yml, pr.yml, snapshot.yml) only run Lucee 7 + SQLite. Suggested fix: rewrite line 21 to "runs weekly across Lucee 6, Lucee 7, Adobe CF 2023, Adobe CF 2025, and BoxLang", drop "Engine support is hard-gated", and change "verified per release" in the BoxLang section to "exercised weekly". This rewrite also incidentally removes the redundant "every release ... on each release" phrasing in the same sentence.
Extended reasoning...
What the bug is
The new cfml-engines.mdx page is positioned as engine-selection guidance — its TL;DR matrix marks Adobe CF 2023/2025 and BoxLang as "Production-supported? Yes", and line 21 backs that claim up with a CI-gating story:
The framework's CI matrix (
.github/workflows/compat-matrix.yml) runs every release against Lucee 6, Lucee 7, Adobe CF 2023, Adobe CF 2025, and BoxLang on each release. Engine support is hard-gated.
And in the BoxLang section:
Wheels' BoxLang compatibility is verified per release in the same CI matrix as Lucee and Adobe CF.
Both sentences are factually wrong, and the workflow file they cite says so explicitly.
Step-by-step proof against .github/workflows/compat-matrix.yml
- The workflow self-describes as informational. Lines 1–2 read:
# Compatibility matrix: runs all engines x databases on a weekly schedule and on manual dispatch./# Non-blocking — informational only.This is the file's own header comment. - Triggers are weekly cron + manual only. The
on:block (lines 5–9) isschedule: - cron: '0 2 * * 0'(Sunday 02:00 UTC) plusworkflow_dispatch. There is norelease:,push: tags:,pull_request:, orworkflow_run:trigger. The matrix does not run on release at all. - Failures are explicitly suppressed. Line 18:
continue-on-error: true. Line 20:fail-fast: false. A failing Adobe CF or BoxLang job does not fail the workflow and does not cancel sibling jobs — the antithesis of "hard-gated". - The actual release/PR pipelines run a single engine.
pr.ymlline 31 names the test job "Lucee 7 + SQLite (LuCLI)";snapshot.ymldoes the same;release.ymlcontains zero references toadobe,boxlang,lucee6, orcfengine. Adobe CF and BoxLang are not part of any release-blocking gate.
So a reader trusting line 21 — "every release is gated against my engine, so my engine is safe" — is being misled. Adobe CF and BoxLang are tested informationally, weekly, with failures suppressed, not gated.
Why this is normal severity, not nit
The page's stated purpose is engine selection (it has a literal "Pick an engine" section and a "Production-supported?" column in the TL;DR). The CI-gating claim is the load-bearing justification for marking Adobe CF and BoxLang as production-supported. Misrepresenting that gating on the page whose entire job is to advise production engine choice is materially misleading, not stylistic.
Addressing the duplicate-claim refutation
A separate bug flagged the redundant "every release ... on each release" wording on the same line as a nit. The refuting verifier was correct that fixing the factual claim (rewriting to "runs weekly across …") removes the redundancy for free, so I am folding that observation into this single comment rather than filing it twice.
How to fix
In web/sites/guides/src/content/docs/v4-0-0-snapshot/start-here/cfml-engines.mdx:
- Line 21: replace "runs every release against Lucee 6, Lucee 7, Adobe CF 2023, Adobe CF 2025, and BoxLang on each release. Engine support is hard-gated." with something like "runs weekly across Lucee 6, Lucee 7, Adobe CF 2023, Adobe CF 2025, and BoxLang. Note that this matrix is informational only — the release pipeline itself runs against Lucee 7 + SQLite."
- BoxLang section: change "verified per release" to "exercised weekly" (or similar).
Alternatively, if the team wants the documentation to become true, add a release: trigger and remove continue-on-error: true from compat-matrix.yml so the engines actually are release-gated. The PR description ("the CI matrix gates every release on all three engines") would then also be accurate.
|
|
||
| <Aside type="note"> | ||
| The `wheels start`, `wheels stop`, `wheels reload`, and `wheels test` commands all assume the Lucee Express bundled with the CLI. On Adobe CF you'll use `box server start/stop/restart` instead, and reload via `?reload=true&password=<your-password>` directly. Generators (`wheels generate ...`) are pure file-system operations and work the same regardless of engine. |
There was a problem hiding this comment.
🔴 The Aside on lines 69-71 contradicts step 4 directly above it. Step 4 correctly explains that wheels migrate works on any engine because it just HTTP-hits /wheels/cli on the running server, but the Aside then claims wheels start, wheels stop, wheels reload, and wheels test all assume bundled Lucee Express. Per cli/lucli/Module.cfc, wheels reload (line 516) and wheels test (line 3674) follow the exact same detect-port + HTTP-request pattern as migrate — only wheels start and wheels stop are genuinely LuCLI-bound. Recommend narrowing the Aside's list to just wheels start and wheels stop.
Extended reasoning...
The contradiction
Step 4 (lines 56-62) tells the reader: "Run migrations the way you would on Lucee: wheels migrate latest. The wheels CLI hits the running server's /wheels/cli endpoint, which works the same on every engine." The Aside immediately below (lines 69-71) then says: "The wheels start, wheels stop, wheels reload, and wheels test commands all assume the Lucee Express bundled with the CLI." These two claims can't both be right — wheels migrate, wheels reload, and wheels test are all built the same way.
Verifying against the CLI source
In cli/lucli/Module.cfc:
runMigration(line 3222):$requireRunningServer()thenmakeHttpRequest('http://localhost:#serverPort#/wheels/cli?command=migrate&...')— pure HTTP, engine-agnostic.reload(line 516):$requireRunningServer()thenmakeHttpRequest('http://localhost:#serverPort#/?reload=true&password=...')— same shape. It additionally calls$purgeServerCfclasses(), but that helper checksif (!len(lucliHome)) return;(line ~4424) and silently no-ops when there's no LuCLI-managed server, which is exactly the Adobe CF / CommandBox case.runTests(line 3674):$requireRunningServer()thenmakeHttpRequest('http://localhost:#serverPort#/wheels/app/tests?...')— same shape.start(line 558): shells out viaexecuteCommand('server', ...)to launch a Lucee Express server. Genuinely LuCLI-bound.stop(line 648): also LuCLI-bound.
$requireRunningServer/detectServerPort (line 4893) checks lucee.json, .env PORT, and ports 8080/60000/3000/8500 — exactly the ports CommandBox / Adobe CF would expose (the doc itself uses port=8080 in step 3).
Step-by-step proof
- A reader follows step 3:
box server start cfengine=adobe@2025 port=8080. CommandBox boots Adobe CF on 8080. - They run
wheels migrate latest(step 4). The CLI callsdetectServerPort()→ finds 8080 → HTTPs tohttp://localhost:8080/wheels/cli?command=migrate. Works on Adobe CF. ✓ (Doc agrees.) - They edit a model and run
wheels reload. The CLI callsdetectServerPort()→ 8080 → HTTPs tohttp://localhost:8080/?reload=true&password=....$purgeServerCfclassesno-ops. Works on Adobe CF. ✗ (Doc says it won't.) - They run
wheels test. The CLI callsdetectServerPort()→ 8080 → HTTPs tohttp://localhost:8080/wheels/app/tests. Works on Adobe CF. ✗ (Doc says it won't.) - They run
wheels start. The CLI shells out to LuCLI to launch Lucee Express. Doesn't help an Adobe CF user, who already has CommandBox running their server. ✓ (Doc agrees.)
Impact
The Aside steers Adobe CF users away from wheels reload and wheels test, which work fine on their setup, and tells them to "reload via ?reload=true&password=<your-password> directly" — which is literally what wheels reload does. Careful readers will also notice the contradiction with step 4 and lose trust in the page.
Suggested fix
Narrow the list to the two commands that are actually LuCLI-bound:
The
wheels startandwheels stopcommands assume the Lucee Express bundled with the CLI; on Adobe CF you'll usebox server start/stop/restartinstead.wheels migrate,wheels reload, andwheels testwork on any engine because they just HTTP-hit the running server. Generators (wheels generate ...) are pure file-system operations and work the same regardless of engine.
| --- | ||
| title: CFML Engines | ||
| description: Run Wheels on Lucee, Adobe ColdFusion, or BoxLang. The wheels CLI ships with Lucee; the framework runs on all three. | ||
| type: explanation |
There was a problem hiding this comment.
🟡 The new page declares type: explanation in its frontmatter, but the repo's style guide (writing-docs.mdx lines 60-68) enumerates exactly five valid types — tutorial, howto, concept, reference, section — and explanation is none of them. explanation is the upstream Diátaxis name for what this repo renames to concept, so the author appears to have used the wrong vocabulary. Given the page contains a <Steps> block with shell commands and ends with a Related <CardGrid>, change to type: howto (the style guide explicitly assigns those traits to howto and forbids them on concept).
Extended reasoning...
What the bug is
The new file web/sites/guides/src/content/docs/v4-0-0-snapshot/start-here/cfml-engines.mdx introduces a frontmatter value (type: explanation) that is not on the repo's allowlist of Diátaxis types. The style guide at web/sites/guides/src/content/docs/v4-0-0-snapshot/contributing/writing-docs.mdx lines 60-68 explicitly enumerates the five valid types: tutorial, howto, concept, reference, section. The condensed style guide at web/sites/guides/STYLE.md:47 lists the same four Diátaxis types (without section). Neither document mentions explanation.
Why this happened
In upstream Diátaxis, the four quadrants are named tutorial / how-to / reference / explanation. This repo renamed explanation → concept. The author used the upstream Diátaxis term, which is intuitive but breaks the local vocabulary.
Step-by-step proof
- Open
web/sites/guides/src/content/docs/v4-0-0-snapshot/start-here/cfml-engines.mdxline 4 — value istype: explanation. - Open
writing-docs.mdxlines 60-68 — the allowlist istutorial | howto | concept | reference | section. Noexplanation. - Grep
type: explanationacross all ofv4-0-0-snapshot/— zero other matches. This page is the sole introducer. - Cross-reference content traits: writing-docs.mdx says concept = 'no commands, no steps' — but this page contains a
<Steps>block (lines 38-72) with bash commands. It says howto = 'Ends with a Related<CardGrid>' — and this page does exactly that (lines 99-111). So the natural fit ishowto, notconcept.
Why existing code doesn't catch this
The Starlight content schema in web/sites/guides/src/content.config.ts uses the default docsSchema() and does not validate the custom type field, so the build does not fail. STYLE.md notes that 'A future Vale rule rejects mixed types', but no such rule exists yet, so the violation is silent today.
Impact
Low — the page renders fine. But it's the only page in ~180 v4-0-0-snapshot/*.mdx files using a non-allowlisted value, which breaks an invariant the style guide explicitly documents and that future tooling (Vale rules, content-classification scripts) will key off.
Fix
One-line edit: change line 4 of cfml-engines.mdx from type: explanation to type: howto. (concept would be defensible if the page were rewritten to drop the <Steps> block, but as written, howto is the closer fit per the style guide's own criteria.)
Summary
Resolves #2494.
The Start Here section pointed every new developer at LuCLI without explaining that LuCLI is a Lucee-only convenience. The framework runs on Adobe ColdFusion 2023/2025 and BoxLang as well — and the CI matrix gates every release on all three engines — but Adobe CF / BoxLang users had no documented path from "I want to use Wheels" to "I have a running dev server."
What this adds
start-here/cfml-engines.mdx:wheelsCLI is Lucee-only (LuCLI doesn't redistribute Adobe CF; BoxLang's launcher is separate)box server start cfengine=adobe@2025, and a manual Adobe CF installstart-here/index.mdx's CardGrid (sidebar.order: 6, after the tutorial)installing.mdxso Adobe / BoxLang users aren't silently steered into the Lucee-only flowTest plan
/v4-0-0-snapshot/start-here/cfml-engines/— page renders with the TL;DR matrix, all sections, and the "Related" CardGrid links resolve./v4-0-0-snapshot/start-here/— new "CFML Engines" card appears after the Tutorial card./v4-0-0-snapshot/start-here/installing/— top tip appears before the Java prerequisite Aside, with a working link to the new page.Generated by Claude Code