Skip to content

Releases

v0.11.2

Choose a tag to compare

@github-actions github-actions released this 14 Nov 12:30
b59e4fe

[0.11.2] — 2026-11-14

Screenshots and docs for the latest changes. No package changes.

Docs

  • New screenshots of the dashboard (healthy, failing checks with the new index and slow-source warnings, explain, dark mode) and of recommender:doctor, recommender:bootstrap (now with the speed probe) and the new recommender:doctor --probe
  • README, dashboard guide and operations describe the speed checks, the index check and --probe

v0.11.1

Choose a tag to compare

@github-actions github-actions released this 14 Nov 12:17
5b930ee

[0.11.1] — 2026-11-14

Catch slow queries before they run, not only while they run.

Added

  • Index check in doctor and the dashboard: each interaction table needs an index on its timestamp column and one starting with its user column; a missing one is a warning with the $table->index(...) to add (Laravel 10.35+)
  • Speed probe: recommender:doctor {feed} --probe (also run by recommender:bootstrap) runs each part once on real data — job reads, a personal and a guest list with every source / booster, the catalog tail, the recommendable scope / filter and the cards — times each, flags anything over slow_ms / slow_query_ms and names the slowest SQL. Read-only; works before the first scores exist

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 14 Nov 11:57
ad08565

[0.11.0] — 2026-11-14

Find slow queries in your own code.

Added

  • Speed checks in doctor and the dashboard. The package now times every call into app code while serving (sources, boosters, the recommendable scope or filter, cards, groups, catalog tail) and every SQL query while update-scores / build-neighbours run, and records how long each job run took. Anything slower than slow_ms (200 ms), slow_query_ms (1000 ms), slow_scores_seconds (300) or slow_neighbours_seconds (1800) shows up as a warning with the part's name (e.g. recommendable scope (Post) or the SQL) and what usually fixes it, and is logged at most once an hour. Only slow events are stored (cache, 7 days, max 20 per feed); the timers add no measurable cost (stress numbers unchanged). See operations → slow queries

v0.10.10

Choose a tag to compare

@github-actions github-actions released this 14 Nov 08:21
a07de63

[0.10.10] — 2026-11-14

Support dates and CI actions. No package changes.

Docs

  • Laravel 12 support ends with the first release after 31 March 2027, together with Laravel 10 and 11 (Laravel's own security fixes for 12 end on 24 February 2027). From then on the package supports Laravel 13 and newer

Changed

  • CI: actions/checkout@v7, softprops/action-gh-release@v3 (Dependabot)

v0.10.9

Choose a tag to compare

@lam0819 lam0819 released this 14 Nov 07:41
0ab4310

[0.10.9] — 2026-11-14

Support dates. No package changes.

Docs

  • README supported-versions table: new Laravel security fixes until and Supported here until columns. Laravel 11 support ends with the first release after 31 March 2027, like Laravel 10 (both no longer get Laravel security fixes)

v0.10.8

Choose a tag to compare

@lam0819 lam0819 released this 14 Nov 07:33
10b129c

[0.10.8] — 2026-11-14

Security checks in CI. No behaviour changes.

Added

  • Security workflow (every PR, main, weekly): composer audit of the runtime dependencies for Laravel 10–13 (Laravel 10 and 11 report-only: both are end of life and have advisories that will not be fixed, e.g. CVE-2026-48019), and Psalm taint analysis of src/ that fails on any Tainted* finding. See SECURITY.md
  • Dependabot updates for the CI actions; on the repository: Dependabot alerts and security updates, secret scanning with push protection

Changed

  • Feed names are validated in one place (FeedDefinition::validName()), which the taint analysis recognises. Its first run flagged the dashboard's ?feed= reaching a query: not exploitable (the value must name a configured feed, names are limited to [A-Za-z0-9_-.], and it is a bound parameter), now provably so
  • CI: actions/checkout@v5 (v4 ran on a deprecated Node version)
  • README supported-versions table: Laravel 11 no longer gets security fixes from Laravel (since March 2026); Laravel 12 needs 12.60+ for Laravel's own fixes

v0.10.7

Choose a tag to compare

@lam0819 lam0819 released this 14 Nov 06:59
d839ada

[0.10.7] — 2026-11-14

PHPStan level 10 (max). No feature changes.

Changed

  • Static analysis at PHPStan level 10 for src/ and the examples (was 8): every value read from config, the cache or a database row is checked or converted to its type before use, through the new Support\Value helper (int, float, string, id, map; same results as a PHP cast for the values these sources hold). No ignores, no baseline
  • A feed's filter, cards, groups or interactions class that does not implement its contract now fails with a clear InvalidArgumentException naming the feed and key (before: a TypeError)
  • Cache entries that are not what the package wrote (e.g. edited by hand) are ignored instead of failing: non-id entries in cached lists are dropped, and a list entry whose ids is not an array is treated as missing
  • FeedDefinition::list() returns only non-empty strings (list<string>)

Stress numbers are unchanged within run-to-run noise (update-scores ~91k events/s; similar() cold 3 queries / warm 0).

v0.10.6

Choose a tag to compare

@lam0819 lam0819 released this 14 Nov 06:27
8c49e54

[0.10.6] — 2026-11-14

Supported versions in one table; no package code changes.

Docs

  • README: Supported versions table (Laravel 10–13 × PHP 8.3–8.5), showing what CI tests and the Laravel 10 end date
  • Release steps: main is protected (all CI checks must pass before merge, no direct pushes); releases go through a pull request, then the merge commit is tagged

Changed

  • CI: the full suite also runs on PHP 8.5 with Laravel 11 and 12

v0.10.5

Choose a tag to compare

@lam0819 lam0819 released this 14 Nov 06:02
65a352b

[0.10.5] — 2026-11-14

Correct scores outside UTC, and safer impressions. If your app timezone is not UTC, run recommender:rebuild-scores after upgrading (see UPGRADE).

Fixed

  • Scores in apps whose timezone is not UTC (Laravel 11–13). update-scores read its stored watermark back in UTC (Carbon 3) while interaction tables hold app-local times. East of UTC (e.g. Asia/Hong_Kong) each run re-read the last hours and counted events again; west of UTC (e.g. America/New_York) new events could be skipped. The watermark is now read in the app timezone (also in the dashboard and rebuild-scores). Laravel 10 (Carbon 2) was not affected. Present since 0.0.1
  • Redis cache store: the cached neighbour version came back as a string, so it was never reused and every similar() call ran an extra query. Found by the new Redis CI job

Security

  • Guest pages no longer count impressions by default (only with 'impressions' => true). Guests have no seen-set, so every reload counted again and anonymous traffic could push an item's quality down, which rebuild-scores cannot undo. Opt back in with 'impressions_guests' => true, behind a rate limit
  • cards_vary_by variants are capped per card (card_variants_max, default 20, oldest dropped), so unvalidated attribute values cannot grow one cache entry without limit

Changed

  • CI: PHP 8.5 with Laravel 13; Laravel 10 on PHP 8.5 is an install + class-loading check, because Laravel 10's test tools (Testbench 8 / Pest 2) do not install on PHP 8.5; and a job that runs the whole suite on a real Redis cache store (RECOMMENDER_TEST_CACHE=redis)
  • README: Laravel 10 support ends with the first release after 31 March 2027

v0.10.4

Choose a tag to compare

@lam0819 lam0819 released this 14 Nov 02:20
61bc80a

[0.10.4] — 2026-11-14

Docs checked against the code. No package code changes.

Docs

  • Tuning: removed content from an app-specific feed (pet / shop classes that do not exist in the package, "lessons from a real inspiration feed", video posters). Recipes now use package classes plus clearly marked classes you write; new "Common pitfalls" table; recipes in A–D order
  • Maths: neighbour cut-offs (neighbours_min_co_count, neighbours_max, history_per_user), what rank(i) means, booster term in the blend, the exact exploration interleave rule, relaxed diversity caps, Math::fromAge is exp(−age / halfLife) (≈ 0.37 after halfLife, not a true half-life)
  • Reference: origin can also be 'tail'; queued warm() carries the attributes you pass (not the user model); impression writes described correctly (two bulk updates, more for new rows); ~270 pages/s matches the measured run
  • Operations: generic FAQ and SQL example (no app-specific wording); current version in the release example
  • Performance: cold similar() is 3 queries in the summary table too; page title
  • Tutorial / how it works / CONTRIBUTING / AGENTS / agent skill: origin values, FeedPage fields, storage classes, Laravel ^10–^13, locks: fallback wording, app-specific lines removed
  • Config comments: cache_store null means Redis when reachable, else CACHE_STORE; links point to docs/tuning.md and docs/operations.md

Changed

  • examples/blog: SponsoredShopSource / SponsoredShopBooster renamed to SponsoredAuthorSource / SponsoredAuthorBooster; they read only sponsored_author_ids (the sponsored_shop_ids fallback is gone)