Description
Precision Live Rates brings real, account-accurate UPS, USPS, FedEx, DHL, and Stamps.com prices into WooCommerce’s cart and checkout. No flat-rate guesswork, no aggregator markups bolted on top of the carrier rate, no rate drift between cart and checkout. The numbers your customers see are the same numbers you’d see on the carrier dashboard for the same parcel.
Under the hood, the plugin packs each cart into the smallest viable parcel using a true 3D bin-packing algorithm (volume-then-SKU-then-product-id deterministic sort, ships-alone overrides honored, custom-packed dimensions for soft goods supported), POSTs the parcel to ShipEngine over HTTPS, dedupes the rate response by carrier+service, and caches the result on your server so identical carts don’t trigger redundant API calls. The same RateService::quote() entry point feeds Classic Checkout, Blocks Checkout, and the WP-CLI wp precision-rates test-rate command — so cart, checkout, and your terminal all return byte-identical rates within the cache TTL.
The diagnostic surface is built for real-world support load. The Rate Test admin screen captures every quote attempt’s full request and response from ShipEngine into a 1-hour transient and surfaces it inline (collapsible, color-coded by HTTP status) so when a customer reports “no shipping options,” you can see exactly which carrier returned what. The Services screen auto-discovers every carrier:service_code flowing through the rate filter and lets you uncheck the ones you don’t want shown. The Plugin Status panel on the Overview tab reports the running version, saved API key state, active carriers, cache TTL, and current markup at a glance — so verifying “is the new code actually live with my settings” is a glance, not an SSH dive.
Privacy and compliance are first-class. The plugin transmits only postal codes, country codes, and parcel dimensions to ShipEngine — never customer name, email, IP, billing address, or order ID. Suggested privacy-policy boilerplate auto-registers with WP’s Settings Privacy editor on activation. Personal-data exporter and eraser hooks are wired so the WP Tools Export/Erase Personal Data flows recognize the plugin as compliant. EU/UK merchants can flip on a Settings Privacy toggle to render a “Shipping rates calculated using ShipEngine — Privacy policy” line under the cart and checkout shipping options.
Highlights
- Real carrier rates via ShipEngine’s
/v1/ratesendpoint — UPS, USPS, FedEx, DHL Express, Stamps.com all behind a single API key. Or connect UPS / USPS directly with your own developer credentials. - True 3D bin-packing via the
dvdoug/boxpackerlibrary. Define your box catalog under WooCommerce Box catalog and items pack into the smallest viable box, ships-alone items respected. - Cart = checkout, byte-identical, within the cache TTL. Single quote pipeline shared by Classic Checkout, Blocks Checkout, and WP-CLI.
- Encrypted credentials at rest via
sodium_crypto_secretbox, derived per-install fromwp_salt('auth') . AUTH_KEY. The plugin refuses to encrypt anything when AUTH_KEY is missing or matches the WP install placeholder. - Per-carrier markup to bridge negotiated rates to retail-equivalent prices. ShipEngine returns each carrier’s negotiated rate (UPS often runs 30-50% below ups.com retail); set “UPS markup %” to 65-75 to display retail-equivalent prices without overcharging USPS shipments.
- Rate Test diagnostic screen captures the raw request/response of every quote — when checkout shows a price you didn’t expect, this is the source of truth.
- Services whitelist auto-discovered from carrier responses; uncheck what you don’t want shown to customers.
- GDPR-compliant out of the box. Privacy policy boilerplate, WP exporter/eraser hooks, opt-in cart disclosure line.
- i18n-ready — English (source), Spanish (es_ES), French (fr_FR) bundled. Other locales contribute via translate.wordpress.org once the plugin lists, or via pull request to the repo.
- HPOS-required. No legacy order-table compatibility shims. Modern WC only.
Out of scope
The plugin is intentionally focused on rate calculation. It does not purchase shipping labels, generate manifests, schedule pickups, sync tracking webhooks back to order status, or integrate with multi-vendor marketplaces (Dokan, WCFM). For label printing and fulfillment, use ShipStation / ShipEngine’s own dashboard or a separate WC label plugin.
Privacy & data handling
This plugin transmits cart/shipment data to a third-party rate aggregator (ShipEngine, https://www.shipengine.com/) over HTTPS to calculate live carrier rates. Specifically, on each rate quote the following is sent:
- Origin postal code + country (and optionally street/city/state, as configured in plugin settings)
- Destination postal code + country (and street/city/state if the customer supplied them)
- Parcel weight and dimensions, computed from the cart contents
The customer’s name, email, phone, IP address, billing address, and order ID are NOT transmitted. Successful rate responses are cached on your server for a short, merchant-configurable duration (60–3600 seconds, default 60). The cache is keyed on parcel dimensions and origin/destination ZIP only — it is not keyed on or attributable to any individual customer.
EU/UK merchants should turn on Settings Privacy “Display privacy disclosure on cart/checkout” so a small “Shipping rates calculated using ShipEngine — Privacy policy” line renders under the cart and checkout shipping options. Suggested privacy-policy boilerplate is auto-registered with WP’s Settings Privacy Policy guide editor on plugin activation.
The plugin also registers no-op personal-data exporter and eraser hooks with WordPress so the Tools Export Personal Data and Tools Erase Personal Data flows recognise it as compliant — there is nothing per-customer to export or erase, but the hooks are present so the privacy admin’s audit trail correctly accounts for the plugin.
Full data-flow documentation, including the GDPR / CCPA / Quebec Law 25 compliance summary, is in PRIVACY.md at the repo root. ShipEngine’s own data-handling practices are at https://auctane.com/privacy-policy/ (Auctane is ShipEngine’s parent company).
External services
Precision Live Rates calls third-party shipping APIs to obtain live carrier rates. No external service is called until the merchant has explicitly enabled and configured at least one carrier source. The data sent is limited to what is needed to compute a shipping price — see the Privacy & data handling section above for the exact payload.
ShipEngine (https://www.shipengine.com/)
* What it is: a rate-aggregation API that fronts UPS, USPS, FedEx, DHL Express, and Stamps.com.
* What is sent: origin postal code, destination postal code + country, parcel weight + dimensions, and the configured ShipEngine carrier IDs. No customer name, email, IP, or order ID.
* When it is called: on the cart and checkout pages when WooCommerce asks for shipping rates and the cached rate has expired (default 60 seconds).
* Why: to compute live shipping prices that match what the carrier itself would charge.
* Terms of service: https://www.shipengine.com/terms-of-service/
* Privacy policy: https://auctane.com/privacy-policy/ (Auctane is ShipEngine’s parent company)
UPS Developer APIs (optional, https://developer.ups.com/)
* What it is: UPS’s official rate API.
* What is sent: same shape as ShipEngine, plus the merchant’s UPS account number.
* When it is called: only when the merchant has explicitly enabled UPS direct under Settings UPS direct and saved valid UPS developer credentials.
* Why: lets merchants who have a direct UPS contract bypass ShipEngine and quote against their negotiated rate sheet.
* Terms of service: https://www.ups.com/upsdeveloperkit/agreement
* Privacy policy: https://www.ups.com/us/en/help-center/legal-terms-conditions/privacy-notice.page
USPS Developer APIs (optional, https://developer.usps.com/)
* What it is: the United States Postal Service’s official rate API.
* What is sent: origin and destination postal codes, parcel weight + dimensions.
* When it is called: only when the merchant has explicitly enabled USPS direct under Settings USPS direct and saved valid USPS developer credentials.
* Why: lets merchants who have a direct USPS account quote against USPS retail rates without ShipEngine in the path.
* Terms of service: https://www.usps.com/terms-conditions/general.htm
* Privacy policy: https://about.usps.com/who/legal/privacy-policy/welcome.htm
Screenshots

Overview tab — at-a-glance plugin status, active carriers, cache TTL, markup configuration, and quick-action buttons (clear cache, run rate test, manage services, open settings, re-run onboarding). 
Settings tab — origin address, ShipEngine + UPS + USPS connections with inline Test Connection, packing toggle, per-carrier markup, cache TTL, privacy disclosure toggle. 
Services tab — auto-discovered carrier:service_codewhitelist with diagnostic counts (“Filter state: N enabled, M disabled”) so the merchant can verify saves persisted.
Rate test tab — quote against your live carrier configuration without leaving the admin. Shows final rates with markup applied PLUS the raw ShipEngine request and response inline (collapsible). 
Cart with live rates — UPS Ground, USPS Priority Mail, FedEx Ground rendering at the merchant’s chosen markup, with optional EU/UK privacy disclosure line. 
Onboarding wizard — first-activation 4-step flow that takes a merchant from “just clicked Activate” to “first rate quoted” in under three minutes. 
Audit log — append-only record of state-changing admin actions (settings saves, box CRUD, service-filter changes, cache clears, ShipEngine connection tests). Filter by event type, paginate, export to CSV.
Installation
- Upload the plugin files to
/wp-content/plugins/precision-live-rates/, or install via the WordPress Plugins screen. Activate. - The first-activation onboarding wizard auto-launches: 4 steps from “just activated” to “first rate quoted” in under three minutes. Welcome ShipEngine API key (with inline Test connection) Origin address Run a test quote.
- (Optional) Define your box catalog under WooCommerce Precision Live Rates Boxes. Without a box catalog, the cart aggregates into a single representative parcel; with a catalog, items 3D-bin-pack into the smallest viable box.
- (Optional) Tune per-carrier markups under Precision Live Rates Settings Markup. UPS typically benefits from a 65-75% markup to bridge negotiated retail; USPS rates already match retail, so leave at 0.
- Verify the live cart shows expected rates. Use the Rate Test tab to simulate any cart against your live carrier configuration without leaving the admin.
Requirements
- PHP 8.2 or higher
- WordPress 6.4 or higher
- WooCommerce 8.5 or higher with High-Performance Order Storage (HPOS) enabled
AUTH_KEYdefined in wp-config.php (rotate via https://api.wordpress.org/secret-key/1.1/salt/ if you’ve never customized it)- A free or paid ShipEngine account, OR UPS/USPS developer credentials. The onboarding wizard walks you through ShipEngine signup.
FAQ
-
How do I get a ShipEngine API key?
-
Sign up at https://dashboard.shipengine.com/ — the free sandbox tier returns synthetic rates that work end-to-end for testing. Once you’re ready for production, the same dashboard issues
LIVE_…keys; connect at least one carrier (USPS via Stamps.com Connect is free and the easiest start) under ShipStation/ShipEngine Settings Shipping Carriers, then paste the key into Precision Live Rates Settings ShipEngine. The Test Connection button below the key field pings/v1/carriersand lists everything connected — use it to confirm the key authenticates before going live. -
Why are the UPS rates I see lower than ups.com retail?
-
ShipEngine returns each carrier’s account/negotiated rate. For UPS specifically, that’s typically 30-50% below ups.com retail (UPS heavily discounts via aggregators to compete with USPS). To display retail-equivalent prices to customers, set the UPS markup % under Precision Live Rates Settings Markup. 65-75% bridges the gap for most accounts; check a few real shipments via the Rate Test tab to calibrate. USPS rates from ShipEngine already match retail — leave the USPS markup at 0.
-
Can I use my own UPS / USPS developer account instead of ShipEngine?
-
Yes. Under Settings UPS direct or USPS direct, paste your client ID + client secret. The plugin uses OAuth 2.0 client-credentials flows for both carriers. Sandbox and production toggle with a single checkbox. You can run UPS direct + USPS direct + ShipEngine simultaneously — rates from all three sources merge into a single deduped list at checkout.
-
How do I hide a shipping service from customers?
-
Trigger at least one rate quote (open the cart with a shippable address). Then visit Precision Live Rates Services. Every
carrier:service_codethe plugin has seen is listed as a checkbox. Uncheck what you don’t want, save. The change applies to the very next cart view — the plugin auto-flushes WC’s shipping cache on save. If a service still shows up after saving, the cause is almost always a downstream cache (Varnish, Breeze, browser, CDN) serving a stale checkout page; the diagnostic count at the top of the Services screen tells you whether the save itself persisted. -
What does “Combine parcels” do?
-
Default on. When no box catalog is configured, the plugin can either ship each cart line as its own parcel (carriers bill each one — 4 mugs = 4 UPS labels = 4× the cost), or aggregate the cart into one representative parcel by stacking items along their smallest dimension. The default “combine” behavior is what most small shops want; toggle off under Settings Packing if you genuinely need strict per-item billing. Once you configure a box catalog under Precision Live Rates Boxes, items pack into real boxes regardless of this setting.
-
Why is the cart still showing old rates after I changed something?
-
A few possibilities. (1) The plugin’s own rate cache. Default TTL is 60 seconds; click “Clear cached rates now” on Overview Quick actions to bust it immediately. (2) WC’s shipping transient. Auto-flushed on every settings save, but if you saved via raw
update_option()the auto-flush didn’t fire — clear from Overview. (3) Editing a product’s weight/dimensions/shipping class auto-invalidates the rate cache, so 0.2.2+ shouldn’t have this issue from product edits. (4) Downstream cache (Cloudways Varnish, Breeze, browser, CDN) serving stale checkout HTML. The Services tab’s diagnostic count distinguishes “save didn’t persist” from “downstream cache is stale.” -
Does it support international shipping?
-
It returns whatever the carrier returns for international destinations. The plugin’s address-fallback logic currently optimizes for US ZIPs (auto-derives state from ZIP when the customer leaves it blank); other countries pass through. There is no separate customs declaration workflow yet — declared values and dimensions pass through to the carrier; carriers handle customs ingestion. Canadian and UK postal-code province/region inference is on the roadmap (BACKLOG E4).
-
Where do I report bugs or request features?
-
GitHub issues: https://github.com/sulemanshahjahan/precision-live-rates-for-wooCommerce/issues. Please include WordPress version, WooCommerce version, PHP version, plugin version, and (for rate-related issues) the relevant
<details>block from Precision Live Rates Rate test Raw ShipEngine I/O. The Logs tab also captures debug output when “Verbose debug logging” is enabled in Settings Cache & diagnostics — the most recent entries are usually the most relevant.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Precision Live Rates for WooCommerce” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Precision Live Rates for WooCommerce” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
0.2.39
- WP.org reviewer round 3.
OnboardingWizard::renderField()refactored to take typedbool $requiredand?int $maxLengthparameters instead of an opaque$extraAttrsHTML-fragment string. Every dynamic value is now individuallyesc_attr()-escaped at the echo site, eliminating theWordPress.Security.EscapeOutput.OutputNotEscapedwarning without resorting to a phpcs:ignore. Fixed two more 404 URLs in the External services + Privacy sections: ShipEngine terms now points tohttps://www.shipengine.com/terms-of-service/and the privacy policy tohttps://auctane.com/privacy-policy/(ShipEngine’s parent company).
0.2.38
- Hotfix for the admin-page styling regression introduced in 0.2.37: the CSS enqueue’s
strpos($hookSuffix, ...)check was matching against the text domain string instead of the admin menu slug, so theprecision-live-rates-adminstylesheet never enqueued on a fresh install. Pinned the check toAdminScreen::PAGE_SLUGso it stays in sync with the menu slug regardless of what the text domain is renamed to.
0.2.37
- Text domain now matches the WP.org-assigned plugin slug. Renamed from
precision-live-ratestoprecision-live-rates-for-woocommerceacross every__(),_e(),esc_html__(), etc. call (251 sites), the plugin header, thePlugin::TEXT_DOMAINconstant, the privacy exporter/eraser slug, the WC Blocks integration name, thephpcs.xmlconfigured text domain, and the language file names. Existing translations on translate.wordpress.org will now resolve correctly once the plugin is published. The admin menu slug (?page=precision-live-rates), CSS class prefixes, option/transient keys, and hook prefixes are unchanged.
0.2.36
- WP.org reviewer remediation round 2.
dvdoug/boxpackerupgraded from 3.12.1 to 4.1.1 (InfalliblePackerPacker::throwOnUnpackableItem(false),getKeepFlat()getAllowedRotation()). Minimum PHP bumped 8.1 8.2 to match the new boxpacker requirement. Vendor dev artifacts (*.feature,*.py,*.ps1,vendor/dvdoug/boxpacker/docs/,vendor/dvdoug/boxpacker/features/) now stripped from the submission zip via the build script’s extension + path excludes.BoxCatalogScreen::carriersField()now runs each POSTedallowed_carriersentry throughsanitize_key()before the value reachesupdate_option(). Fixed two USPS URLs in the External services section that returned 404.
0.2.35
- WP.org reviewer remediation. Removed all premium-tier license / auto-update infrastructure references from shipped code (no License tab, no
registerLicensing()method, no premium-tier mentions in the readme) so the plugin is fully GPL-compliant per Guideline 5. Renamed the PHP namespace from the genericAcme\PrecisionRatesto a project-specificPrecisionLiveRatesper the prefix-uniqueness guideline. Tightened nonce handling in the SettingsPage and BoxCatalogScreen guard methods —$_POST['_wpnonce']now flows throughsanitize_text_field()beforewp_verify_nonce(). Removed the comparative-marketing paragraph from the description per directory-content rules. Added aRequires Plugins: woocommerceheader. Replaced broken GitHub URLs in the plugin header. Expanded the External services section with explicit data-flow, ToS, and privacy-policy links for ShipEngine, UPS, and USPS.
0.2.34
- WP.org Plugin Check round 3 — final cleanup pass. Plugin slug renamed from
wc-precision-ratestoprecision-live-ratesto clear thetrademarked_termreviewer warning (wcis reserved for WooCommerce trademark protection). Bulk rename touches text domain, hook prefixes (precision_live_rates_*), constants (PRECISION_LIVE_RATES_FILE/_DIR), CSS asset handles, form-field prefixes (plr_*), and the plugin entry filename (precision-live-rates.php). The three remaining AuditLog SQL warnings (WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber,UnfinishedPrepare, and the$wpdb->insert()DirectQuerywarning) are now suppressed with the correct phpcs rule names — the previous phpcs:disable bands hadWordPress.DB.PreparedSQL.NotPreparedlisted, which is a different sniff than thePreparedSQLPlaceholders.*family that Plugin Check actually flags. Result: zero Plugin Check errors, zero warnings.
0.2.33
- Plugin Check round 2 — moved the auto-update-bridge code out of the WP.org-bundled tree so the forbidden
pre_set_site_transient_update_pluginstoken no longer appears in any shipped file. ExcludedWP-ORG-SUBMISSION.mdand any root*.mdfrom the submission build. Removed the redundantload_plugin_textdomain()call (WP 4.6+’s just-in-time loader handles this). Migrated the AuditLog INSERT to$wpdb->insert()to clearUnescapedDBParameterwarnings.
0.2.32
- WP.org Plugin Check remediation pass. ABSPATH guards added to every PHP file under src/; 20 throw-site interpolated values wrapped in esc_html() or annotated as chained-Exception;
Tested up to:bumped 6.6 6.9; readme tags trimmed 12 5; short description trimmed to 121 chars; .gitkeep files excluded from the build script; composer.json now ships alongside vendor/; $_SERVER[‘REMOTE_ADDR’] now flows through wp_unslash + sanitize_text_field; AuditLog SQL strings inlined into $wpdb->prepare() to clear false-positive UnescapedDBParameter warnings; TransientStorage prefix-DELETE warnings annotated.
0.2.31
- Internal infrastructure work. No user-facing changes.
0.2.30
- Customer-facing polish (BACKLOG E5). Three cart/checkout enhancements: (1) delivery-date badges — small “Arrives Wed, May 6” labels appended to each shipping option, with relative phrasing for today/tomorrow; (2) carrier logos — small inline-SVG marks (UPS, USPS, FedEx, DHL, Stamps.com) prepended to each rate label using carrier-brand colours but generic text marks (no trademark issues); (3) free-shipping threshold — flips the cheapest rate to FREE once the cart subtotal exceeds the configured value. New Settings Customer-facing polish section with three toggles (delivery dates ON, carrier logos ON, threshold cents 0 = disabled). New
WooCommerce\CustomerPolishclass with 14-test coverage.
0.2.29
- Audit log (BACKLOG E8). New
Audit\AuditLogclass + custom DB table records every state-changing admin action: settings saves, box CRUD, service-filter changes, cache clears, ShipEngine connection tests. New “Audit log” tab on the AdminScreen renders the most recent 100 entries with filter-by-event-type + paginated history; CSV export available. 30-day retention via daily cron (precision_live_rates_audit_prune); the cron event + retention window are filterable. Schema bootstraps idempotently viadbDelta()onadmin_initso first-time installs see the table appear without an explicit activation hook. 10-testAuditLogTest+ newInMemoryWpdbtest double covering insert / SELECT / count / pagination / prune / CSV / event-slug stability.
0.2.28
- International ZIP / postal-code coverage (BACKLOG E4). New
Support\AddressInferencefree function class extracted from the ShipEngine mapper:stateFromPostalCode($postal, $country)dispatches by ISO country code to US (50 states + DC + PR), Canada (10 provinces + 3 territories via the leading postal-code letter), or GB / UK (ENG / SCT / WLS / NIR via the postcode area prefix). Other countries pass through with empty state — ShipEngine doesn’t strictly require it for non-US/CA shipments.ShipEngineRateMapper::buildAddress()now uses the new helper for any country with no user-supplied state, so a Toronto M5V address with state blank producesstate_province: ONin the ShipEngine payload, an Edinburgh EH1 address producesSCT, etc. 49-test parametricAddressInferenceTestcovers ~20 Canadian postal-code prefixes, 16 UK postcode areas, and the dispatch-by-country surface.
0.2.27
- WordPress.org submission prep. Plugin header URIs and Author updated from placeholders to the real values; readme.txt Contributors set to
sulemanshahjahan; Description string in the plugin header updated to reflect the actual ShipEngine/UPS/USPS/FedEx/DHL surface; Tested up to bumped to 6.6. Static pre-flight scan against plugin-check expectations: zero hits for eval/exec/system/shell_exec/passthru/proc_open, zerosslverify=>false, zerounserializeof HTTP bodies, zero translation calls without text domain, all__()/_e()/etc.calls use the staticprecision-live-ratestext domain. Newcomposer ciscript bundleslint + stan + test + probe-mofor one-command pre-submission verification.
0.2.26
- readme.txt polish for WP.org review (BACKLOG E7 partial). 4-paragraph description with concrete selling points; removed stale “no aggregators” non-goal that contradicted the ShipEngine integration; expanded FAQ to 8 questions covering ShipEngine signup, UPS rate negotiation, UPS/USPS direct, service hiding, combine_parcels, cache invalidation, international shipping, bug reports; new Screenshots block referencing 6 PNGs in /assets/ (placeholder until live captures land); README.md rewritten for the developer/contributor audience with an architecture skim and the prod-vendor classmap dance documented prominently. Trimmed in-readme changelog to the most recent five releases — full history stays in CHANGELOG.md.
0.2.25
- Privacy notice + GDPR consent (BACKLOG E6). New
Admin\PrivacyNoticeclass wires three things: (1) a suggested privacy-policy boilerplate auto-registered into WP Settings Privacy Policy guide editor, naming ShipEngine explicitly and enumerating exactly what is and isn’t transmitted; (2) WordPress personal-data exporter + eraser hooks that report the plugin as compliant (the cache is keyed on parcel dimensions, not customer identity, so there’s nothing to export or erase); (3) a merchant-controlled toggle (Settings Privacy) that, when enabled, renders a small “Shipping rates calculated using ShipEngine — Privacy policy” line under the cart and checkout shipping options. Default off; EU/UK merchants should turn it on. NewPRIVACY.mddocuments the full data flow, retention windows, and compliance posture against GDPR / CCPA / Quebec Law 25.
0.2.24
- i18n bundle (BACKLOG E3). Plugin is now fully translatable:
load_plugin_textdomainwired onplugins_loaded,.potregenerated against the live source (192 strings), and Spanish (es_ES) and French (fr_FR) translations bundled. Set the WordPress site language to Español (España) or Français (France) to see the AdminScreen tabs, onboarding wizard, settings, and Rate Test screen render in the chosen locale. NewCONTRIBUTING.mddocuments the translation contribution flow.
0.2.23
- Onboarding wizard fix: Step 2 (origin address) now redirects forward to the test-rate step on a successful save instead of re-rendering the same screen with a “saved” notice. The “Save & continue” button label now matches what the button actually does.
0.2.22
- First-activation onboarding wizard (BACKLOG E2). Replaces the cold settings-tab landing with a 4-step flow that takes a merchant from “just clicked Activate” to “first rate quoted” in under three minutes: welcome ShipEngine API key (with inline Test connection) origin address run a test quote finish. Skip-out link on every step; “Re-run onboarding” button under the Overview tab.
0.2.21
- Test suite restoration (BACKLOG E1). 315 tests 389 tests, all green; phpstan level 8 and phpcs both clean. Two genuine bugs fixed along the way:
usStateFromZip()mislabelled MA ZIPs (010xx-027xx) as Puerto Rico and didn’t recognise RI (028xx-029xx); and the cache-clear admin-post handler was crashing because the$tabUrlclosure variable wasn’t imported.
For the full per-release history including 0.1.0 through 0.2.20, see CHANGELOG.md in the repo.
