v0.7.0
Project hygiene + test coverage pass. No schema migration, no
behaviour change for production traffic; pure improvement of the
project's correctness guarantees and contributor surface.
Added
SECURITY.md— vulnerability reporting policy (GitHub Security
Advisories preferred,paul@argoud.netas fallback), expected
response timeline, scope boundaries vs upstream (mxchat-basic /
DuckDB / WordPress core), supported-versions table, and the
hardening defaults that ship enabled..github/ISSUE_TEMPLATE/— modern form-schema templates for bug
reports and feature requests;config.ymldisables blank issues and
routes vulnerability reports to a private Security Advisory instead
of a public issue.composer auditjob in CI — runs on production deps only (the
release zip ships--no-dev, so dev advisories don't reach end users).szepeviktor/phpstan-wordpress+phpstan/extension-installer
added torequire-dev. WordPress stubs auto-loaded; PHPStan level 6
is now clean with no per-call ignoreErrors needed.- PHP 8.4 added to the lint + phpunit CI matrices.
- 183 new unit tests covering every previously-untested class in
includes/— see the Tests section below.
Changed
- CI hardening:
actions/checkoutbumped v4 → v6 (Node.js 24, no more
"Node.js 20 actions deprecated" annotations).- PHPStan is no longer
continue-on-error— the previous run
after the szepeviktor/phpstan-wordpress bump confirmed level 6 is
silent, so PHPStan now blocks the build like the other jobs. Path
to level 7/8 still tracked inphpstan.neon.dist.
phpstan/phpstanbumped from^1.11to^2.0to support
szepeviktor/phpstan-wordpress ^2.0(which requires PHPStan 2.x).
Fixed
uninstall.phpwas leaking three sidecar options across reinstalls:
mxchat_duckdb_cache_gen(added in 0.6.0),mxchat_duckdb_reprocess_state
andmxchat_duckdb_pinecone_migration_state(both added in 0.4.0) weren't
in the delete list. Fixed by moving the option list into a single array
with an inline pointer todocs/CONFIGURATION.md → Sidecar optionsso a
future addition is harder to miss.wp mxchat-duckdb cache --flushstill used the legacyLIKE DELETE
onwp_optionsinstead of the O(1) generation-counter bump introduced in
v0.6.0. Migrated toMxChat_DuckDB_Plugin::bump_cache_generation(); the
command now also reports the before / after generation numbers.wp mxchat-duckdb syncprogress bar jumped from 0 % to 100 % at the
first batch (the legacy code calledmake_progress_bar(…, 1)and then
tried to tick by the total). The bar is now lazily created on the first
callback with the actual total, and subsequent callbacks tick by the
per-batch delta.- Two French strings were hardcoded in
assets/admin.js("vecteurs"
suffix on the test-connection + sync-complete status lines) bypassing the
mxchatDuckDB.i18n.*localisation surface. NewvectorsSuffixi18n key
added;fr_FR.poupdated,.morecompiled.
Tests
The biggest single jump in test coverage since the project started:
57 → 240 tests, 100 → 857 assertions, 5/20 → 20/20 classes covered.
Every class in includes/ now has at least one dedicated test file;
estimated per-line coverage on business paths went from ~10 % to ~65-75 %.
PreVectorQueryTest(7 tests) — Search_Adapter's v0.6.0
short-circuit hook: previous-non-null bypass, plugin-disabled
fall-through, empty-vector fall-through, happy path with full
Pinecone response shape, namespace/bot_id/default fallback chain,
top_k fallback chain, exception swallowing with admin-notice transient.ProxyAuthTest(11 tests) — Pinecone_Proxy auth + per-namespace
rate limit: missing/empty/wrong api-key rejection, legacy global
wildcard, per-namespace token isolation (the v0.6.0 hardening
contract), precedence rules, namespace from JSON body or query
string, 120-req/min ceiling enforcement, per-namespace bucket
isolation, weird-namespace-name md5 hashing.OptionsSanitizeTest(16 tests) — enum allowlists, regex strips
(SQLi hardening ontable_nameandmotherduck_database), numeric
clamps on every bounded option, boolean coercion, runtime-telemetry
preservation across admin saves, dimension-change guard branches.VectorStoreSchemaTest(11 tests) — migration runner ordering
(v0 → v1 → v2 → v3, resume-from-v1, no-op when at target),
per-request memoisation (and its keying on backend|table|dim),
FLOAT[N] vs TINYINT[N] column branching, HNSW index gating,
table_info()count/null branches.VectorStoreQueryRunTest(12 tests) — top-K orchestration:
dim mismatch throws, cache hit bypasses SQL, cache miss writes
result, dedup over-fetch (the v0.6.0 fix —LIMIT top_k × 3),
Pinecone-style filters compile into WHERE, metric branching
(cosine / l2sq / ip).PineconeMigratorTest(11 tests) — constructor guards (api-key,
host),normalise_host()strips scheme + trailing slashes,
pinecone_to_row()with canonical + legacy metadata keys, null on
missing values, chunk_index/total_chunks string-to-int coercion,
STATE_OPTIONconstant pinned.MysqlSyncTest(13 tests) — detect_kb_columns presence + cache,
full_sync row skip behaviour for malformed embeddings, bot_id
propagation from KB column, incremental cutoff atlast_sync_at - 120s,
cascade-delete authorisation (4 paths: missing nonce, wrong nonce,
missing capability, both nonce variants).CompactorTest(6 tests) — skip paths (disabled / sync too
recent), orphan detection + chunked DELETE,max_deletescap,
KB pagination (the v0.6.0 memory fix), unreadable-table throw.VectorStoreFacadeTest(23 tests) — every public write/read
helper: upsert (empty noop, dim mismatch, skip malformed,
batched INSERT OR REPLACE, cache-gen bump, single-quote escape,
chunk-size filter), delete (by-ids + by-source-url + cache bump),
count/list/fetch contracts, Parquet I/O round-trip,
storage_estimate float32 vs int8,current()singleton.HealthEndpointTest(7 tests) — JSON shape that monitors
depend on, 200/503/disabled branching, full payload assertions,
metrics-snapshot keys pinned.AsyncReprocessTest(10 tests, 1 skipped) — Action Scheduler
integration: enqueue_batch + dedup, process_post counter bumping +
re-throw on failure, status() snapshot merging, cancel_all.PostReprocessorTest(17 tests, 1 skipped) — full reprocess
pipeline including API key resolution per provider (OpenAI /
Voyage / Gemini), vector_id md5 alignment, post-type mapping,
failure paths (no permalink, empty content, WP_Error from submit).AdminAjaxTest(14 tests) — all 4 AJAX handlers' nonce +
capability gates, input sanitisation, batch_size clamp [1, 50],
default ['post', 'page'] fallback, error-path messages.MotherDuckConnectionTest(7 tests) — token + database-name
guards (defence-in-depth on top of the Options sanitiser), init_sql
composition with single-quote escape in tokens.CliTest(18 tests) — 11 sub-commands' argument parsing, error
paths on missing required flags, output via WP_CLI::log/success/error,
table format via format_items, command registration under the
documented namespace.
Tooling
tests/bootstrap.phpgrew a substantial library of reusable
test primitives:MxChat_Test_WPDB— pattern-matching$wpdbmock with callable
pagination +NOT_FOUNDsentinel.MxChat_DuckDB_Connectionrecording-mock pattern (anonymous
classes inline per test).Connection_Factory::$cachereflection injection so
new Vector_Store()sees the mock without a real backend.apply_filtersoverride registry via
$GLOBALS['__test_filter_overrides'].- Nonce shim driven by
$GLOBALS['__test_valid_nonces']. - "First response wins" AJAX shim defeating production's
catch (\Throwable)re-wrap. - WP_Query matcher closures + Action Scheduler queue stub.
- WP_CLI shim with
MxChat_Test_CliExitfor::errorthat die()s. MxChat_Utilsstub recording everysubmit_content_to_dbcall.
Notes
- The continue-on-error flag on the PHPStan CI job was dropped after
this bump's first CI run confirmed level 6 is clean with the new
szepeviktor/phpstan-wordpress stubs. - No public API surface changed in this release; safe drop-in upgrade
from 0.6.0.