Skip to content

v0.48.0

Choose a tag to compare

@MustafaShaaban MustafaShaaban released this 23 Oct 08:36
· 18 commits to main since this release
2b42435

The rest of the CoreX revamp's stage 0 and its first quality release: mail stays where it should (spec 113, R0.2, DECISIONS #381 to #385), screens that tell the truth (spec 114, R0.3, #390 to
#398), kit and public page safety (spec 115, R0.4, #400 to #407), and quality checks on every
release (spec 116, R1.1, #410 to #419).

Read Client impact before updating. Four things can change on a live site:

  • A site whose .env says APP_ENV=local, development or staging, or whose operations mode is Development or Staging, now keeps its mail in Email Studio instead of sending it. Check both before updating.
  • Kit pages that still reference the stats or testimonial patterns lose those two sections for visitors until someone edits them, and pattern buttons with no Brand action link or contact page are hidden. Perego runs the Company kit: check its pages.
  • The bookings, careers and newsletter routes now judge a reCAPTCHA v3 token by its action, hostname and score: a site's own form must request its token under the route's action.
  • The Overview, Security Center and Insights now say what is true, so some rows that read "Done" or "Hidden" may now read "Not set", "Off" or "Not configured".

Added

  • Quality checks on every release (spec 116, R1.1 of the CoreX revamp). A new CI job, Quality checks, opens every CoreX admin screen and tab and every theme template in eight cells (375 and 1280px, light and dark, left to right and right to left) on a WordPress with the Company kit applied. It checks for sideways scroll, WCAG 2.2 AA (axe-core, contrast and target size included) and raw developer keys. At phone width it checks tables, 44px controls, the rail and text at 200%. It also checks focus and Escape, reduced motion, the empty, loading, failed and refused states of every screen, untranslated words (a pseudo-locale run) and a front-end budget: layout shift, image sizes, lazy images, CoreX bytes per page, and block assets only where the block is. What main showed when the checks were written is in tests/e2e/quality/known-failures.json, each entry with the story that fixes it. A new defect fails the job. node scripts/quality-known-failures.mjs prints the list.
  • The admin's colour tokens are checked for contrast, dark and light, before any browser opens (ContrastMatrixTest).
  • A PHP translation lint (php scripts/i18n-lint.php), the product completion audit (npm run audit:completion) and the admin read and form budgets (composer test:performance) run in CI. The translation template corex.pot is generated on every pull request and attached to every published release.
  • A client merge check (scripts/client-merge-check.mjs) merges a release candidate into a throwaway clone of a client repository. It names a conflict in a file the client records as a local edit, runs the client's suites and writes a report for the release record. CI proves it on a generated client site.
  • wp eval-file scripts/clean-test-residue.php lists and, when told to, removes the submissions test runs left on a development site. It refuses a production site.

Changed

  • One setting decides whether a site is a development site (spec 113). APP_ENV in .env, a value the network locks or the corex_app_env option decides first, and locks the operations mode (the Operations screen says what locks it and offers that environment's mode, Coming soon and Maintenance); then the operations mode; then WordPress's environment type, where local now counts as Development. A site in Coming soon or Maintenance stays closed to visitors whatever APP_ENV says. Email Studio, Insights and the Settings diagnostics show the same answer and where it comes from.
  • Mail stays on a development or staging site (spec 113). Every email, from every CoreX path, from WordPress and from other plugins, is captured into Email Studio → Delivery logs, named by what sent it ("Form notification", "Newsletter: new post", "WordPress: password reset", "Other: wp_mail"), and nobody receives it. Staging sends for real once a provider is set and live delivery is on. A switch on the Email Studio overview, Capture only CoreX mail, lets WordPress's and other plugins' mail through. Without CoreX Mail active, such an email is not sent and is recorded in the activity log. A production site, and a site in Coming soon or Maintenance with no development or staging APP_ENV, sends exactly as before.
  • A flow's "Run marked test" holds its emails on every site (spec 113), production included: the result lists each with a link to it in Email Studio, and the Test tab says so before the button is pressed.
  • Email Studio says on every tab what happens to mail on this site: delivered for real, captured, or blocked, with live delivery, the provider, what decided, and any kind of email that does not follow it.
  • Email Studio's log shows the newest mail first however many emails are stored, the overview counts say they are of the last 100 emails, and captured and held emails are deleted after 30 days (they were kept forever).
  • The Overview shows only true states (#390). Brand reads "Done" only with a company name and a logo, otherwise "Not set" with a link to Brand settings. Insights / PageSpeed reads "Connected" only with a saved key whose last run completed, "Key saved, not checked yet", "Keyless (shared quota)", or "Error" with the reason after a failed run. Captcha reads "Not configured" for None or Honeypot and when the captcha add-on is off. Spam protection says "Honeypot only" or "Honeypot and ". Login protection reads the Security Center, and hardening has a row of its own. A fact that cannot be read says "Could not check".
  • "Default login endpoints: Hidden" only when they are (#391). The Security Center row reads "Reachable" while login protection or hiding is off, and "Recovery active: the default login is reachable" while COREX_LOGIN_UNGUARD is set, with how to end recovery. The login guard, the Security Center and the Overview ask one rule.
  • A PageSpeed run that could not run shows an error, never a grade (#392): "Could not run", the reason and Retry, with no score. Failed runs stored by earlier releases as 50/D are shown as failures with their message; none is deleted.
  • Insights security events are complete (#393). Operations-mode changes, refused visits to CoreX screens (one event per counted entry), sign-in lockouts and access-request decisions are in the activity log, and the card shows the newest five of them whatever else happened, and from when it has records. Events from before the update stay in their own logs.
  • The Add-ons screen reports what really happened (#395). A failed activation shows WordPress's reason, leaves the add-on off, writes no feature flag and shows no kit prompt. An add-on active for the network ("Managed by the network administrator") or installed as must-use ("Must-use: always on") has a switch that cannot be used. Each enable and disable is in the activity log.
  • The login screen shows no single sign-on option (#396), whatever the stored setting says, and Settings → Brand no longer offers "Enable SSO login section". The stored value is left in place.
  • Blog Pro says plainly that it does not count readers yet (#397). Without reading data it shows one line instead of the reading-signals panel and the period line, and the Sharing card is gone.
  • Dependency advisories of 2026-10-22: the docs site takes astro 7.3.3 (GHSA-mpr7-6m5w-76rw, low), and the sprintf-js exception is removed because GitHub withdrew its advisory (GHSA-hp3w-g68c-fv3c). Development dependencies only; no package ships them.
  • A browser test run cleans up after itself. It prints the site it will write to, refuses one in Production mode served from a real host name, removes the submissions it made and fails if it left any without a test's marker. The test fixture plug-ins say "Test fixture" where a person sees them. COREX_BASE_URL has no default any more: npm run test:e2e and npm run test:quality refuse to start until it names the site to test (it used to fall back to http://corex.local).
  • A Client impact section names each running client site, Muva, Perego and Mizzey, or says that no client site is affected. The changelog test enforces it from this release on.
  • The completion audit's "coming soon" rule no longer matches the name of the Coming soon mode, only a promise ("(coming soon)", "is coming soon"), and the audit reads every folder CoreX ships instead of a list that left most add-ons out.
  • In CI, a failing linter no longer stops the audit, the unit tests and Jest in the same job, so one run reports every failure.
  • A reset gives back the pages the owner had (DECISIONS #400). - Applying a kit now records each page it replaces or adopts (title, content, template, status) and the site's front-page settings before it changes them. - wp corex reset restores those pages with the same ID and address instead of deleting them, and puts the front page back. - A page replaced before this release, with nothing recorded, is kept as it is and listed as "kept: no earlier version recorded". - --dry-run lists each page as created (will be removed), replaced (will be restored) or adopted (will be emptied).
  • The setup wizard says what it records (DECISIONS #401). It no longer says it backs the site up. The Backup step lists the pages the plan will record, recommends a full backup with the host or a backup plugin, and keeps Apply off until the person confirms they have one.
  • Shipped patterns make no claims for the site (DECISIONS #402, #403). - The stats, testimonial and logo-cloud patterns are marked as samples. A visitor sees nothing of them until someone changes them in the editor; an editor sees them labelled "Sample: replace before publishing". - The theme's header, footer and mega-menu patterns link to the site's real pages or show the label as text, and take contact details from Brand settings or leave them out. No shipped pattern links to # any more. - A build check fails when a pattern gains an invented figure, an example address, a 555 number or a link to #.
  • The front-page hero can be read and its buttons used (DECISIONS #404). The hero heading is readable against the hero in the light and dark palettes. The hero and call-to-action buttons stand apart from their section and link to the brand's primary action link or, without one, the site's contact page; with neither, they are not shown. Heading colours elsewhere are unchanged.
  • The flow editor never loses edits without asking (DECISIONS #405). - The header says "Unsaved changes" or "All changes saved". - Back to flows, Publish, Move to draft, Close and Run marked test ask to save first, so what is published or tested is what is on screen. - Leaving the page with unsaved changes raises the browser's warning. - The Test tab says which version it tests.

Fixed

  • Email Studio's tabs fit the screen. A wide delivery log made every tab wider than the page, cut off at its edge.
  • Saving Settings changes only what was changed (#398). A save wrote every field of every section, and saved the switches of an add-on that was off as off: saving Brand with Corex Media off switched WebP conversion off. Now a section whose add-on is off or not installed is not written, and a field is written only when its value was changed.
  • The captcha "Test verification" button appears (#394). It looked for a field id the Settings form does not use and was loaded on a screen name WordPress does not give the Settings screen. It now sits under the secret key field once a provider and both keys are saved, and says the provider's answer in words (works, wrong key, a key missing, cannot reach the provider) in a region a screen reader announces; until then the field says what is needed.
  • Visitors can register, subscribe, request a call and apply for a job when a captcha provider is on (DECISIONS #406). - With Turnstile, hCaptcha or reCAPTCHA v3 set up, these four routes refused every visitor for a check no form showed. - The account registration form and the newsletter signup block now carry the provider's check and send its token. - The routes answer "Please complete the check before sending." or "The check failed. Please try again.", and store and send nothing without a passed check. - A site's own call request or job application form carries the check through Corex\Security\FormChallenge; the bookings and careers READMEs show how.
  • The captcha provider's script is printed on the page (DECISIONS #407). It was queued after WordPress had printed the footer's scripts, so it never reached the page. This affected corex-forms' protected forms too.
  • The slug fields of a new flow and of an Email Studio template check what is typed again. Their pattern was invalid under the rules browsers now compile a pattern with, so the browser ignored it and logged a console error. An unescaped - in a character class is now escaped.

Client impact

  • Before updating a live site, check two things: its operations mode (CoreX → Operations & Security) is Production, Coming soon or Maintenance, and its .env, if it has one, does not say APP_ENV=local, development or staging (.env.example ships APP_ENV=local). Either one makes the site keep its mail in Email Studio instead of sending it.
  • Production mail is otherwise unchanged. A client site whose code sends through the Mailer seam, with no provider and live delivery off, keeps sending.
  • Local and staging copies start capturing mail: a copy whose operations mode is Development or Staging, or whose WordPress environment is local, development or staging, keeps its mail in Email Studio instead of sending it. Check a copy's mail there after updating.
  • Muva and Perego: their production sites send as before if the two checks above hold; their local copies keep their mail. Mizzey is pinned to v0.42.0 and is not affected until it moves.
  • A test that spies on wp_mail() on a development install now sees mail kept before wp_mail(): CoreX's own test helper tests/Support/MailDelivery.php gains a DELIVER mode for tests that exercise production sending. A client repository that carries copies of CoreX's tests takes the updated helper.
  • Nothing to do for the screens. Owners of both client sites read different, accurate rows on Overview, Operations & Security, Insights and Blog Pro. Muva's captcha test button appears. Muva has no PageSpeed key, so its Insights shows "Could not run" with the reason instead of a D.
  • Check the image conversion switches if Corex Media was ever off on a site. Values already switched off by the old save are not repaired. Open CoreX → Settings → Media and read "Convert uploads to WebP", "Convert JPEG uploads" and "Convert PNG uploads"; turn back on any the owner wants and save. Muva and Perego both have Corex Media on, so their values were not hit.
  • A login screen where an owner had ticked the single sign-on box loses a button that did nothing. A client repository that carries copies of CoreX's own tests takes the updated tests/Unit/Config/LoginSsoTest.php, AdminAppearanceTest.php and SettingsTabsTest.php.
  • Code that used BrandingService::loginSsoEnabled(), ControlPanelStatus or DomainStatus must stop: they are removed. No client site uses them.

Spec 116, the quality checks (tests, scripts and CI only):

No client site is affected at runtime: this release changes tests, scripts and CI only.

  • Muva and Perego: nothing changes on the site. After the next framework merge, the client repository's CI runs the new Quality checks job against its CI's own WordPress. That WordPress holds the framework's plug-ins and add-ons, not the client's site, so the job checks the framework's screens with the same known failures. The browser suite's new teardown fails a client's own spec that leaves an unmarked submission behind. The suite refuses to run against a site in Production mode served from a real host name, such as a live site. Before a tag, the release is now merged into a copy of each client's repository and that client's suites are run.
  • Mizzey: not on this release (pinned at v0.42.0); nothing changes until it moves.
  • Muva runs corex-captcha (reCAPTCHA v3) with its own forms. They are not declared to CoreX, so its pages load nothing new and its forms keep their own token handling. Nothing to do.
  • Perego runs corex-ui and the Company kit, and does not run corex-captcha. Check its pages for references to the corex/stats, corex/testimonial, corex/hero and corex/cta patterns (<!-- wp:pattern {"slug":"corex/stats"} /--> and the like): such a page changes without being edited. - The stats and testimonial sections are hidden from visitors until someone edits them. - The hero and call-to-action buttons are hidden unless the site has a Brand "Primary action link" (CoreX → Settings → Brand) or a published page at /contact/. Set one of the two. - The newsletter signup block's status line gains a data-corex-captcha-message attribute. Perego's theme is its own, so its theme patterns are unchanged.
  • Sites that applied the Company kit stop showing the sample stats and quote to visitors on pages that still reference those patterns, until someone edits them. Pages saved in the editor before this release keep what they hold.
  • A site with corex-ui active gets hero and call-to-action buttons that link to its Brand "Primary action link" or its contact page, and are hidden when it has neither. Set the link under CoreX → Settings → Brand.
  • Code that constructs these classes by hand passes their new arguments; the container does this for you: - NewsletterSignupRenderer: a Corex\Security\FormChallenge; - CaptchaAssetController: a CaptchaChallenge, and its forms registry may be null; - FormChallengeContextFactory: a Corex\Security\ChallengeSettings in place of the config; - ResetCommand: a KitPageReader.
  • A site's own call request, job application or newsletter form that posts to these routes with reCAPTCHA v3: the reCAPTCHA v3 token is now judged like a flow's: it must have been requested under the route's action (corex_register, corex_newsletter, corex_call_request, corex_job_application), come from the site's own hostname (or captcha.allowed_hostnames) and reach the configured score. Request the token with grecaptcha.execute(siteKey, { action: 'corex_call_request' }) (or the route's own action), or print the field through Corex\Security\FormChallenge, which does it for you.
  • Neither client runs the CoreX theme, reset, the account add-on or builder flows. Mizzey is not on this release.