Project status
Version 0.48.1 · updated 2026-10-14
This page exists so you do not have to read the git history to find out what you are adopting. Everything below is traceable to something in this repository — a spec, a policy file, a test exclusion, a source directory. Nothing here is stated from memory, and the sources are named so you can check any line of it.
Three statuses, and they mean specific things:
| Meaning | |
|---|---|
| Stable | Built, tested, and used. Its contract is not expected to change. |
| Partial | Real and working, with a named gap. The gap is stated, not implied. |
| Planned | Not built. Listed so you can tell “we chose not to yet” from “we forgot”. |
One thing worth knowing about how this list is written. The failure this project keeps catching in
itself is a framework describing a capability it does not have: an upload validator whose
docblock referenced a store nobody had written, a mail add-on documenting attach() against a driver
that took four arguments, a notification action whose label the client could never render. Each was
found by comparing a claim to the code, and each is closed. This page is written to be checkable for
the same reason — so the next such gap is found by a reader, not by a customer.
Foundation
Section titled “Foundation”| Module | Status | Notes |
|---|---|---|
corex-core | Stable | Container (PSR-11), layered config (.env → options → defaults), routing, middleware, security, cache, jobs, notifications, mail seams, admin shell. |
corex-config | Stable | The admin product: settings, data models, submissions inbox, access, operations, notifications, insights, blog tools. Operations has five modes; Coming soon serves a launch page the theme owns, with a preview link for people without an account (spec 101). A submission can be moved to a trash, restored and deleted for good (spec 105, four of six slices). Exports are CSV, Excel or PDF (spec 103). A reply from the inbox is written in an editor, previewed as the email it will be, and kept on its submission (spec 106, slices 1 to 4 of seven; a reply being written is not kept as a draft yet). On the Data screen several models are exported in one go, and a column that holds personal data is exported only by a person who holds “Export personal data” (spec 109, two of six slices; importing and moving several models are not built). The role matrix can be previewed and applied. A release package is installed from the Releases screen on a site that runs CoreX, step by step, with the recovery link given first; the site can go back to the release before, and the screen shows what happened (spec 107). Not verified on its target: it has not been run on a shared host. |
corex-forms | Stable | Schema, validation, flow builder, submission pipeline, routing, delivery. A form defined in code takes a file, which is stored out of public reach and opened from its submission in the inbox (spec 081); the form’s notification email does not carry the file and prints the number it is stored under. A form defined in code states its wording, can be drawn with a site’s own markup, and is challenged by reCAPTCHA, Turnstile or hCaptcha (spec 104); the two widget providers were not submitted through on a real site. |
corex-blocks | Stable | Server-rendered blocks with the shared provider/renderer split. |
theme/ | Stable | FSE block theme. Presentation only — deactivating it breaks presentation, never data. |
packages/cli | Stable | wp corex make:* generators, version, docs:generate, release packaging. make:site generates what a client repository needs to take framework updates; npm run verify:framework checks it (spec 102). |
Add-ons
Section titled “Add-ons”| Add-on | Status | What is missing |
|---|---|---|
corex-email (Corex Mail) | Stable | Templates, routes, queue, attempt log, Email Studio. A reply leaves in a standard design with a plain-text version beside it, and a site gives its emails its own colours, logo and footer, or its own template, from its own code (spec 106). Live delivery is fail-closed by default — that is deliberate, not a gap. |
corex-guides | Stable | Extendable guide registry + support contact (specs 084, 087). |
corex-media | Stable | WebP pipeline behind an activation gate that only serves the converted file when it passes. |
corex-captcha | Stable | Honeypot, reCAPTCHA, Turnstile, hCaptcha. |
corex-ui | Stable | Modal, drawer, tabs, accordion and layout blocks. The modal and the drawer have a browser test of their own (tests/e2e/block-dialogs.spec.js); no screen reader was listened to. |
corex-careers | Stable | Job posts, applications, CV upload through the protected store (spec 081). |
corex-profile | Partial | Registration, an auth gateway and session listing (src/Account, src/Session). The full profile system is explicitly deferred — ROADMAP.md §15. |
corex-newsletter | Partial | Signed-token subscribe/confirm, a subscriber store, and a notifier that mails the list on publish (src/Subscriber, src/Subscription). No campaign composer, no scheduling, no segmentation. |
corex-bookings | Partial | Call-request capture, routing to a leader directory, and mail (src/CallRequest*). No calendar, availability or rescheduling. |
corex-kit-company | Partial | The most complete kit: setup wizard, page coverage, demo levels, SEO. ROADMAP.md M4 records the remaining section blocks and make:site token inheritance as open. |
corex-kit-portfolio | Partial | Project post type and two blocks. Not the page coverage M4 defines — ROADMAP.md M8. |
corex-kit-woo | Planned | Four files: a blueprint, a gate and a provider. It reserves the seam; it is not a store kit. ROADMAP.md M9, waiting on Woo design and stable gating. |
Known open items
Section titled “Known open items”Each of these is recorded somewhere in the repository already. The source is the point — you can verify every one.
Three browser specs are excluded from a fresh-install run
Section titled “Three browser specs are excluded from a fresh-install run”Two block-editor specs trade a failure between them: whichever opens the editor first fails to see
the inserter, demonstrated in both directions. A trace rules out console errors, failed requests,
php -S versus nginx, worker starvation and the welcome-guide modal; timeouts from 30s to 150s all
failed, and 150s destabilised neighbouring specs. A third, the flow-builder spec, times out
mid-interaction and — unlike the editor pair — has not been shown to be environmental, so it may
be a real slow path.
The editor itself works; smoke.spec.js clicks that inserter successfully whenever it is not first.
These are real coverage gaps, diagnosed down to “needs fresh eyes”.
Source: tests/e2e/playwright.config.js, CANNOT_RUN_ON_A_FRESH_INSTALL.
Arabic typography has layout proof, not type proof
Section titled “Arabic typography has layout proof, not type proof”The RTL acceptance matrix forces dir="rtl" onto English strings, so it proves the layout holds and
proves nothing about Arabic typography. Bidi artifacts visible in those cells belong to the fixture,
not the product. An Arabic catalogue and its own pass are still owed.
Source: specs/079-admin-errors-access-request/evidence/after/acceptance-matrix.md, DECISIONS #196.
Development installs may hold leaked test fixtures
Section titled “Development installs may hold leaked test fixtures”AccessRequestFormTest used to create a subscriber per test and never delete it. Fixed in spec 091,
but an install that ran the suite before that still holds them — 311 on the one where this was found.
Each carries a pending access request, and the denied surface renders its pending state when one
exists, so enough of them make access-request.spec.js find a confirmation where it expects a form.
Repository state is correct; this is only about installs that predate the fix:
wp user list --field=user_login | grep '^corex-079-requester-' | xargs -r -n1 wp user delete --yesThe browser suite also left submissions: every inbox seed and contact-form test added rows that the
inbox, Data, Insights and Settings counts then showed. From spec 116 a run removes the submissions it
made and fails if it leaves one without a test’s marker. What earlier runs left is removed with
wp eval-file scripts/clean-test-residue.php, which lists first and asks, and refuses a production
site.
Source: specs/091-rtl-overflow-and-fixture-leak/ and specs/116-quality-checks/.
Closed, and worth knowing were closed
Section titled “Closed, and worth knowing were closed”Two entries stood under Known open items in v0.39.0 and no longer do. They are kept, briefly, because “was this ever a problem, and how was it dealt with” is a fair question to ask of a project you are evaluating.
Dependency advisories — five bounded exceptions
Section titled “Dependency advisories — five bounded exceptions”npm run verify:dependencies reports PASS across Composer, the root npm workspace and the
docs-site npm workspace as of 2026-10-25: zero findings in Composer and the docs site, and in the
root, four findings covered by four exceptions. Two more left the list when GitHub withdrew their
advisories: sprintf-js (GHSA-hp3w-g68c-fv3c) on 2026-10-22 and braces (GHSA-vfj7-8cjw-p6xm) on
2026-10-23. Ten advisories published since 2026-10-23 (twelve findings) were closed on 2026-10-25 with patched releases
inside the ranges their parents already accept (body-parser, fast-uri, serialize-javascript and zod
in the root; undici and zod in the docs site), with no exception added. That date matters. An advisory is
published by somebody else against a tree that did not move, so this is a measurement, not a
property — on 2026-10-06, with nothing changed here, the gate failed on thirteen advisories, eleven of them
published on 2026-10-05 or 2026-10-06.
None of the four is a fix that was skipped. Each is an advisory with no release this tree can take:
| Package | Advisory | Why it cannot be closed |
|---|---|---|
simple-git 3.36.0 | GHSA-x6jw-m9v5-85vh (critical), GHSA-g4wm-2vf7-vfgr, GHSA-858h-whjf-mvg5 | Fixed in 4.x only. It is installed for @wordpress/env, whose latest release requires ^3.32.3 and calls the package as a function; 4.x exports an object, so an override breaks wp-env start instead of fixing it. Tried, and it failed. |
@simple-git/argv-parser 1.1.1 | GHSA-v5rq-49vh-5v5c (critical) | The parser simple-git 3 depends on; the fixed 2.0.1 belongs to simple-git 4. |
The simple-git four are the ones to read carefully: two are rated critical, and the code
runs. npm run env:start clones WordPress through it. Each advisory is a way round
simple-git’s refusal of dangerous git options, which matters where somebody else chooses what it
is given. Here that is wp-env.json in this repository — one git source, WordPress/WordPress —
and a person who can change that file can already run any command through wp-env’s own
lifecycleScripts. It runs on a developer’s machine only: no workflow uses wp-env, and nothing
under node_modules is shipped. The policy allows a critical finding to be excepted when its
exposure is neither the shipped runtime nor CI; these are reviewed a month sooner than the rest,
on 2026-11-30, and are removed by a lockfile update the day @wordpress/env moves to
simple-git 4.
braces also runs — in npm run lint:css and npm run build, locally and in CI. The defect
is a stack overflow on a deeply nested brace pattern, and the only glob patterns that reach it here
are the built-in defaults of @wordpress/scripts: no tracked file imports a glob library and there
is no custom webpack, stylelint or dev-server proxy configuration. Triggering it would take a
commit to this repository’s tooling configuration, and the result would be one failed job. It is
not in any built asset. The policy forbids excepting a high finding whose exposure is CI, so this
rests on a judgement that the exposure is build tooling with repository-authored input — the same
judgement spec 056 made for minimatch and brace-expansion. The exception says what would
overturn it.
The two extract-zip exceptions are gone, with the package. lighthouse is overridden to 13,
which brings puppeteer-core 25 and @puppeteer/browsers 3.x, and that unpacks without
extract-zip. Nothing here runs that chain — the browser suite drives @playwright/test
directly — so the override was checked for what can be checked: the tree installs, and the one
package that depends on lighthouse loads against it. @wordpress/scripts 36 installs the same
versions by itself, and the override goes when that toolchain upgrade (ESLint 10, stylelint 17) is
done.
Every exception names its dependency path, compensating control, review date and upstream removal
trigger in .github/dependency-security-policy.json.
This section has been wrong twice by standing still. It said “none open” for a month while the
gate failed on main, and after that was corrected it went on saying “one bounded exception”
while the policy file held three. Both were true when written. The gate has run on every pull
request and weekly on main since DECISIONS #224, and is not a required check, so a red result
on main blocks nothing and is only seen by whoever looks. (DECISIONS #224, #226, #227)
This was 24 bounded exceptions as recently as v0.39.0. Closing them needed overrides rather than
npm audit fix: every vulnerable package was a transitive one whose parent pinned it below the
patched version, and what npm proposed instead was a downgrade of @wordpress/scripts from 33 to
19 — which CONTRIBUTING.md forbids. The docs-site half was recorded as blocked by a lockfile
question that turned out to depend on the root being clean, so fixing the root unblocked it and the
Astro 7 migration landed with it. (Spec 089, DECISIONS #206)
Branch protection
Section titled “Branch protection”All six checks that run on every pull request are required on main: the PHP unit suite, the
JavaScript suite, integration against a provisioned WordPress, Playwright, and both CodeQL contexts.
Force-pushes and branch deletion are blocked.
Two things are deliberately not set, and the reasons matter more than the settings:
dependency-securityis not required. It runs on every pull request, but it depends on a third-party advisory service, and a required check that an outage can fail blocks every merge until somebody re-runs it. Requiring it is deferred until it can survive that (DECISIONS #224).- Reviews are not required and admins are not enforced. This is a single-maintainer repository;
both would lock the maintainer out of their own
mainrather than add a reviewer.
Deliberately not built
Section titled “Deliberately not built”These are decisions, not omissions. ROADMAP.md §15 records them, and §16 makes the rule explicit:
roadmap presence does not authorize implementation.
Front-office editor workspace · header builder · mega-menu builder · full client portal · full auth/profile system · Pro licensing UI · animation in wp-admin · advanced WooCommerce internals.
What is next
Section titled “What is next”ROADMAP.md is the durable plan; this is the summary.
- M3 / M4 — navigation, template parts and the complete company-page contract. The substantive product direction, and the only items that would be feature specs rather than remediation.
- M5 — component batches, built when a kit proves it needs them rather than all at once.
- M8 / M9 — portfolio and WooCommerce kit completion.
- Capability Inspector / System Map — every provider, seam, job and integration with live health. Spec 074 added a bounded version to the Models screen; the full map is its natural successor and is deliberately not in 074’s scope.
Nothing here is authorized by appearing here. That is ROADMAP.md §16, and it is the rule this
project has kept to.
This page answers one question — what works today. ROADMAP.md answers what is planned,
CHANGELOG.md what changed, PROGRESS.md where to resume, and DECISIONS.md why. README.md
carries the table of which is which.