docs-and-check-docs
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8143d146e4 |
1.6.1: shared-menu 1.2.3, and render the dashboard to check the pill
The status pill on the shared dashboard is white 11px text over a light overlay. SEO measured it two ways, arithmetic and a canvas read-back in headless Chromium: this plugin's #1a7a52 gave 3.50:1 against a 4.5 minimum, and six of eight family colours failed along with the no-colour fallback. Not fixable by choosing a different card colour. The header is a direct pair and passes at 5.32:1; the pill is a COMPOSITE, and 22% white is a floor — a card has to reach about 7.7:1 before the pill clears 4.5, which is above the whole family band. So it is the shared file or seven plugins giving up the colour the cards exist to carry. 1.2.3 makes the overlay rgba(0,0,0,.18) and this plugin's pill goes to 7.15:1. Verified before copying: the hash, and php -w over both files to confirm the executable code really changed — the diff is the version constant and that one CSS value, nothing else. The new assertion renders the dashboard and reads the pill out of what came back, and it is built around the trap SEO warned about: their first harness printed "no problem" over a code path it never entered, because it stubbed wpmgr_cards instead of wpmgr_dashboard_cards and the renderer took its early return. So the card's own title is asserted first — if the renderer bailed, nothing after it means anything — and the OLD rgba is asserted ABSENT, because a check that cannot tell the two versions apart cannot testify about either. Both proven: against 471b0a2a it fails naming "the old 22% white", and with the card filter removed it fails at 81 bytes rendered. That 81 is the same number SEO reported from their own broken harness, which is independent confirmation it is the same code path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6a789349ec |
1.5.3: shared-menu 1.2.2, and run the glyph style instead of reading it
678f1f03 is withdrawn. It hard-coded the icon box at 36x34, and WordPress declares that parent three times with different sizes — 36x34 open, 35x30 folded, 34x30 under 960px — so a fixed number is correct in one state and 4px too tall in the two a laptop is usually in. cache-manager measured where the ink lands rather than where the box is and found it worse than that: the glyph moved from 2.5px above centre to 2.5px below in the folded states, the same error mirrored, in a state that had been nearly right. 1.2.2 removes the number entirely with width/height at 100%. 1.5.2 is already published with 678f1f03, so this tree shipped the withdrawn version. Checked before anything else, because a later candidate fatalled on every admin page with "Unknown format specifier": that file was never taken here, and the published 1.5.2 emits its stylesheet cleanly — verified by running sprintf over its format string rather than reading it. So the shop is cosmetically off in folded menus, not broken. New assertion, and it is the one this round is really about: the style function is INVOKED and its output captured, rather than the source being read. The fatal that prompted it survived three sessions reading the file, a clean php -l, a clean PHPCS, and two browsers agreeing about the CSS — because every one of those was fed the stylesheet by hand rather than through the printf that produces it. A literal per-cent must be doubled in a format string, and nothing that looks at the file can see that. Proven red with that exact fault rather than an arbitrary one: undoubling the per-cent gives "ValueError: Unknown format specifier ';'". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6114473be0 |
1.5.2: take shared-menu 1.2.1, which centres the glyph
Kristian reported the infinity sign sitting above centre in the admin menu on the live shop. Security traced it to WordPress's own stylesheet rather than adjusting it by eye: #adminmenu div.wp-menu-image is 36x34 and its :before carries padding 7px 0, which is exactly 7 + 20 + 7 for a 20px dashicon at line-height 1. The 1.2.0 rule set line-height 1.4 and inherited that padding, so the pseudo-element was 42px tall inside a 34px parent. 1.2.1 reproduces the box, drops the padding and centres with flex — geometry rather than a nudge, because U+221E sits on the maths axis instead of filling its em box. It is the same half-done abstraction as the escaping fix: the filter made the character configurable and left the geometry tuned for one specific character. Nothing could fail, because the only value anyone ever passed was the one it was tuned for. Verified before copying, including the part that makes the check meaningful: Security predicted php -w WOULD differ this round, since the executable code changed — so equal stripped hashes would have meant the wrong file. They differ, and the diff is the version constant plus the CSS geometry, with wpmgr_css_escape untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f908771f33 |
Take shared-menu.php 1.2.0: the glyph is CSS-escaped, not esc_attr'd
Frozen by Nolimit SEO as 9012fe98, and it fixes something found here: the 1.1.0 glyph went through esc_attr() into a <style> element, where HTML entities are not decoded by the CSS parser. It was protecting by coincidence rather than by working, and Security found the case where the coincidence stops covering — a backslash, which esc_attr leaves alone, is a CSS escape and swallows the closing quote. No injection was possible on any input any of us could construct, so this is hardening rather than a hole, and the value comes from plugin code rather than from a request. The fix changes the alphabet instead of filtering the input: the glyph is emitted as CSS numeric escapes, so what reaches the stylesheet is nothing but backslashes, hex digits and spaces. cache-manager's statement of why that is the right shape is the one worth keeping — the value CANNOT CONTAIN A DELIMITER. "It escapes correctly" is a description, and a whitelist claims the same description while needing to be kept honest against inputs nobody has thought of yet. Verified here rather than accepted: - sha256 matches 9012fe98 before copying. - The "b8d9284b plus two full stops and a phpcs pair" claim is comment-only, measured with php -w over both: one sha256 for the stripped source. - The escaper itself run against seven inputs including a bare backslash, a quote, a CSS breakout, an HTML breakout and a NUL, asserting the output matches nothing outside [backslash, hex, space]. All seven clean. - Correct codepoints, and no mb_* calls, so the hand-written decoder holds on installs without mbstring — which is every install none of us test on. WPMGR_MENU_SHA updated in ci/plugin.conf. SEO's instruction said ci/static.sh, which is their layout, not this one — following it literally would have set a variable nothing reads, green on both sides while the check still asserted the old value. Found by searching for the OLD VALUE rather than the path: zero occurrences of any earlier frozen hash remain anywhere in ci/, tests/ or either workflow root, and the new one appears exactly once. Then proven consumed in both directions, which is the assertion that catches a copy nothing reads: changing the file by one byte moves "got", and changing the value in plugin.conf moves "expected". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3020338378 |
Take shared-menu.php 1.1.0 and keep its hash in one place
The family froze a new copy of includes/shared-menu.php: 184cebdc, contract 1.1.0. Two changes in it for this plugin, which was still on f4862d5c (1.0.0). The menu icon is now an infinity sign, painted from admin_head behind a wpmgr_menu_glyph filter that defaults to it — Kristian asked for it because the family is called Nolimit. And the file's own header said 1.0.0 while its constant said 1.1.0, and it counted five plugins where there are six; Nolimit SEO found both. Taken today rather than when convenient, and the reason is measured rather than tidiness: two plugins were on 1.1.0 and three on 1.0.0 at the same time, so a shop got the glyph or the cog depending on activation order — while every repository's own hash check was green on its own side. A frozen file is a family-wide fact, and a green local check says nothing about the shop. The API change is additive — a new filter and a new function, nothing removed — so this plugin's use of wpmgr_ensure_menu() and wpmgr_menu_title is unaffected, and the default glyph means there is nothing to opt into. The hash now lives once, as WPMGR_MENU_SHA in ci/plugin.conf, checked by ci/static.sh and required by ci_load_conf so an unset value cannot turn the comparison into a no-op. It was previously a literal inside tests/smoke.php as well; two copies of one constant drift, and the copy that drifts is the one nobody remembers. The runtime assertion that remains proves a different fact — that the file is loaded at all — because wpmgr_ensure_menu() only exists if it was. Proven red by appending one line to the shared file: the check names both hashes and says not to edit it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
9f19688900 |
Rename to Nolimit Discounts and move the page under the shared menu
Kristian could not find this plugin in the Nolimit menu, and it still called
itself WooCommerce Email Discount Manager. Both are the display side of the
family rename; neither touches the installed folder.
Plugin Name is now "Nolimit Discounts". The folder, the text domain, the option
prefix and the three tables are deliberately unchanged: WordPress identifies a
plugin as <folder>/<file>, so renaming the folder would not move the
installation on the live shop — it would put a second copy beside it and leave
the old one active. That is a migration with a shim, and it is Kristian's call
rather than a side effect of a label change.
includes/shared-menu.php added, byte-identical to the family copy
(f4862d5c…c63185), and the page moved from the WooCommerce submenu to the
shared parent. The page slug is unchanged, so admin.php?page=… still resolves
and an existing bookmark keeps working — moving a page between parents does not
move its URL.
The label is claimed through the wpmgr_menu_title filter from this plugin's own
bootstrap, NOT by editing the shared file. Which copy of that file a site loads
is decided by activation order, and PHP cannot un-declare a function, so the
first copy wins for the whole request: editing it would make a site with three
of five plugins updated show "Manager" or "Nolimit" depending on who booted
first, and change its mind when a plugin is deactivated. The filter is
idempotent and a plugin still on an older build changes nothing.
The filter is registered before the WooCommerce gate, for the same reason the
updater is: the shared menu's label must not depend on whether this particular
plugin got past a check.
Two assertions, both proven red first. The label is asserted through the filter
rather than by reading the menu, because the menu is only built in an admin
request and the smoke tests run under WP-CLI. And the shared file's sha256 is
asserted, so editing it goes red here rather than going strange on a shop —
appending one comment line produced:
FAIL and the shared menu file is the family copy, unedited
— expected 'f4862d5c…', got '45df6b55…'
Also caught in passing by the kit, working exactly as intended: the new
shared-menu.php was untracked, and "every file the plugin loads is a file the
release contains" failed rather than shipping a zip without it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|