Repository navigation
Releases: Vateron-Media/XC_VM_Dev
Release list
2.6.3-dev.19 (nightly)
Source: Vateron-Media/XC_VM@f671e87
Nightly build from main. Untested — for test servers only.
Changes since 007982aca93c
- Prepare release 2.6.3 (5c0a7f9e)
- test(gateway): give the live vectors test a STREAMS_PATH that exists (7b9198c1)
- fix(gateway): hand a fence MAIN commanded to PHP for its drain (ae452d5d)
- docs(gateway): ADR 0005, the LB plan and the operator notes (2487874d)
- fix(stream): check a catch-up segment's address before the viewer is heard (052737ad)
- feat(gateway): the segment gateway's policy, nginx wiring and shadow comparison (526fcc6e)
- fix(cluster): install an API-mode load balancer without MAIN's database (4d2ecdfd)
- style(admin): space out the Info tab sections (df5d9931)
- test(audit): create watch_refresh for the series delete test (44c33bd5)
- fix(logging): name the refusal counter by SHA-256, not md5 (e2b53d50)
- feat(admin): list the module store without a key, a page at a time (741f8c3a)
- feat(modules): install free store modules without an API key (18b9305f)
- feat(logging): log invalid stream ids and invalid credentials as client refusals (94c62648)
- chore(tools): name console.php by its full path after a restore (29c876db)
- feat(core): own the TMDb refresh queue and stop writing watch_folders (b9f65559)
- fix(migration): keep core tables of migrations out of the module files (efe36762)
- feat(dashboard): copy the HWID on the way to getting a verification key (e5b1acb4)
- feat(admin): drop the modules page's Uninstall action (cd1a9342)
- fix(install): fill the access code's alias and rate-limit zone (69707b9e)
- feat(migration): hand backup tables the core does not own to their modules (b0be9f5b)
- feat(modules): install no module by itself (8d011825)
- Prepare release 2.6.2 (8fb2ef47)
- feat(install): new panels start on the cluster API (04ed6100)
- docs(release): the compatibility code goes after 2.6.2, the next release (468b73d3)
- feat(cluster): count legacy /api calls, and let proxies close it (e7a4c8c6)
- feat(cluster): lay out Cluster Nodes like Manage Servers (b0a6486f)
- fix(update): start the ipset install as an argument list, not a shell command (c99c6e6b)
- feat(update): install ipset with the update, for the blocklist sets (28c7cf2c)
- fix(firewall): no weak hash and no command built from data in the ipset change (4bce9ea5)
- docs(cluster): record the blocks in ipset sets (be74398c)
- fix(diagnose): find MAIN's address in a node's ipset set, and say how to unblock it either way (071901fd)
- feat(install): install ipset on new servers (d298826e)
- feat(firewall): keep the panel's blocks in two ipset sets (7ede2fab)
- docs(cluster): record the load balancer alert and metrics, and the canary's fanout check (7f563e0d)
- ci: run XC_VM_Fanout's agent tests against this panel (4585c82e)
- chore(i18n): translate the cluster alert's title and the keys main added in English only (27ee65a4)
- feat(cluster): the release canary also needs its fanout daemon running (956a9811)
- feat(cluster): alert on load balancers that need attention, and export them in /metrics (1b2405ff)
- test(support): let several processes share one TestDb schema (4e192047)
- fix(cluster): queue nothing granting for a quarantined node (5a23c8ab)
- docs(cluster): record the large blocklist, the flushed one, quarantined commands and actions not sent (316e354f)
- feat(servers): say which servers an action did not reach (b89078f9)
- fix(cluster): reach a quarantined node with its kills, and leave nothing a node in mode 2 cannot read (85ea3d64)
- fix(cluster): sync a large blocklist in parts, and keep none past a flush (fe99b21f)
- chore: group .gitignore and ignore locally installed modules (02f64fdc)
- docs(cluster): record the closed MAIN-LB gaps and refresh the plan's markers (ef14d946)
- fix(install): create the stats and log indexes with the schema (73f1ca58)
- feat(cluster): show the release pin on the Cluster settings tab (57498f4c)
- fix(cluster): never queue a root action a node in mode 2 cannot take (3684e02e)
- feat(admin): rewrite the modules page around module status and the store (7e304f4c)
- feat(modules): list the official store's modules (edc3bfd6)
- feat(modules): run module actions as background jobs (aafaa849)
- refactor(modules): one update check for the cron and the modules page (a8fe5450)
- fix(modules): read config/modules.php fresh on every PHP-FPM master (ece6135d)
- feat(cluster): an RTMP viewer on a load balancer while MAIN cannot be reached (45841c95)
- test: name the covered class in full in every @Covers (73875dd1)
- chore(cluster): add the canary's lines apart from the other open pull requests' (acd5dcb6)
- docs(adr): this entry beside the others' insertion points (ae8156f3)
- docs(cluster): a load test on the test pair (4a7e67f9)
- fix(cluster): the watchdog keeps running on a node with TELEMETRY (2de06fda)
- test(settings): 24 cluster settings with Viewer Record Proof merged (3d9d5072)
- ci: write coverage in the one suite run instead of a second run (39b56074)
- fix(users): show last login and registration dates in the panel timezone (37f3a580)
- feat(cluster): set viewer record proof from the panel, and see when enforce is safe (7f2a27a8)
- docs(cluster): measure the command latency, and leave the SSE downlink (db9e13e5)
- fix(stream): place a load balancer's RTMP viewer with the Redis handler on (fcc7aa7d)
- feat(cluster): a fleet canary for the binaries every server takes from GitHub (c313133d)
- feat(cluster): MAIN moves a node that lost its own streams back to mode 1 (560378f0)
- feat(cluster): mode 2 with the Redis connection handler (366734dc)
- fix(cluster): an RTMP viewer that leaves a load balancer ends its record (5a13c551)
- test(cluster): run an RTMP viewer's mint from MAIN's answer to its record (1d2eba59)
- docs(adr): RTMP and Ministra tokens are read on MAIN alone (88e7de5c)
- docs(cluster): bring the MAIN-LB plan's build status up to date (fcf56bee)
- feat(cluster): close the data plane from the Cluster Nodes page (c9796dfc)
- fix(cluster): an RTMP viewer on a load balancer carries MAIN's mint proof (3384ef0d)
- test(settings): read API mode back with the cluster API on (cda346e4)
- test(cluster): prove a strip's late ack queues the credentials back (157f2796)
- fix(settings): refuse API mode for new nodes while the cluster API is off (f2710b54)
- fix(cluster): keep every connection MAIN closed under a uuid (9b0a8999)
- feat(cluster): let a load balancer serve RTMP viewers, their line checked by MAIN (dccf4468)
- docs(cluster): say how an LB's relayed streams move over to the data plane (1a349ee0)
- fix(cluster): send a node no stream password from the admin player (3a53f5aa)
- fix(cluster): close the two known gaps in MAIN's connection store (56aa22e0)
- fix(cluster): never lose a credential strip's outcome, nor strip below mode 2 (2572f41c)
- docs(cluster): bring the developer guide's limits up to date (3131b279)
- feat(cluster): let new load balancers join in mode 2 (728f1027)
2.6.2-dev.17 (nightly)
Source: Vateron-Media/XC_VM@007982a
Nightly build from main. Untested — for test servers only.
Changes since 8a3b295d18db
- test: start the divergence test's Redis on a free port and wait for it (e390aac6)
- fix(i18n): say where an account's legacy API key is (a97beeb1)
- docs(cluster): rolling update, guided cutover and placement advice (8e0bc99e)
- feat(cluster): placement advice on the Servers page (dacffeda)
- feat(cluster): guided cutover of a load balancer up to mode 1 (e7d3682e)
- feat(cluster): update the load balancers one at a time (510c342c)
- fix(cluster): ask an unanswering agent once per viewer pass; describe mode 2's wait (e1245b96)
- fix(cluster): refuse a mode 2 viewer whose check the agent did not answer (7ac47580)
- fix(cluster): wait longer for the agent in mode 2 and never fall back to MAIN's store (05f677c0)
- fix(vod): run the release parsers through ProcessRunner (99e30eee)
- docs(operations): document maintenance, metrics, alerts, reminders and off-site backups (8b555391)
- feat(backups): copy backups off-site, seal a recovery bundle and test restores (b194cb03)
- feat(alerts): send alerts and expiry reminders by Telegram, webhook and e-mail (15891955)
- feat(monitoring): add /metrics for Prometheus and /healthz (ca105d2d)
- feat(maintenance): close the client APIs and resellers during maintenance (4f1f71bd)
- feat(audit): record what admins change (a643e33f)
- feat(api): named, scoped API tokens in place of the single key (84f13e40)
- feat(auth): two-factor sign-in for admins and resellers (5a8b4bf8)
- fix(i18n): restore placeholders the translator broke (43c04e05)
- feat(dashboard): warn when a server's clock is off MAIN's (84bee4c2)
- feat(service): wait for NTP's first synchronisation at boot (26a5efd7)
- fix(streaming): read a stream token's times on MAIN's clock (2bafab96)
- chore: ignore Playwright MCP output (6d50ef39)
- fix(ministra): restore the handshake methods the main merge dropped (715d4291)
- fix(status, epg): mark the schema with the release and name XMLTV files by SHA-256 (506a638b)
- test(ci): one suite run per pull request with Redis, make test, a faster LB gate and the player_api contract (10c2e0ff)
- chore(i18n): the new and removed panel strings (ec54536b)
- refactor(reseller): one text per action in the reseller logs and the dashboard (eb64326d)
- refactor(settings): drop the eleven fields nothing reads; new installs keep logs 180 and 365 days (f5a71555)
- feat(dashboard): judge every server, add disk, backup, certificate and cache rows, read the map only when shown (bdb12e22)
- perf(epg): dedupe in one pass and render a source set's XMLTV programmes once; imports fetch icons six at a time (69fba1c0)
- perf(logs): batched retention, log-table indexes, one aggregate per stats window, Stream Rank links the stream (75bcb55c)
- perf(cache): read the episodes once, shard the bouquet map, keep the last good run on a failed one (29ea8e9a)
- perf(playlists): cache a playlist under everything it is built from, for any TTL; order and filter the API lists cheaper (e5d6788b)
- feat(update): report a failed migration, dump MAIN before an update, reverse a rollback only for 2.5.x targets (87ac2d96)
- feat(backups): dump the live database before a restore and leave the restored file alone (311f42e6)
- chore: ignore Playwright MCP output (0df8738c)
- feat(vod): carry an M3U entry's title in VodImportResultEvent (39bbcddd)
- fix(vod): drop provider pipe tags from a release name before matching (167dadd7)
- fix(signals): restart the daemon when a Redis signal read drops (37b0c54d)
- docs: Direct Source is the operator's choice, and a stream form tab escapes what it prints (5ff77795)
- fix(admin): edit_proxy and edit_server edit only their own kind of server (b6c5aa10)
- fix(admin): start every record edit from the row as stored (c004d510)
- fix(cluster): hold a node to the mint proof where MAIN withholds its stream secret (a6687b90)
- feat(cluster): bind a node's connection records to the token MAIN minted (2fc8cdd0)
- feat(admin): keep the fields every admin API edit leaves out (654afd02)
- fix: import UserCredits in the users API, list keep_syslog for nodes and post the players' actions in tests (cc0c2a9a)
- docs: describe the quarantine, the updating hold, the cron limit, POST-only player actions and DECIMAL credits (599a2e76)
- chore(i18n): add the message of the commands a quarantine ends (cfcf4d7d)
- test(streaming): pin the Direct Source redirect every client but the web player keeps (0af90d29)
- fix(logs): store MariaDB's errors, keep the note of a manual block and prune System Logs (6ade2284)
- fix(player): sign out, refresh and reorder bouquets only on POST (421444e0)
- fix(admin): keep a line's state, owner and stored text on an edit, and read is_trial as a switch (98194aa9)
- fix(cron): end a cron:servers or cron:streams run that hangs past ten minutes (309b7413)
- feat(cluster): end a node's granting commands when it is quarantined (dcb67ae2)
- feat(cluster): keep a node that reports updating out of routing for a minute (a762f4a2)
- feat(reseller): store balances and prices as DECIMAL(16,4) (a7efd517)
- docs: describe the decided behaviour and the cluster designs awaiting approval (8132bbbd)
- chore(i18n): add the import switches and reword the username guess limit (69a1ab22)
- test(i18n): give the panel its own strings back after the translator test (92e5c7c2)
- feat(cli): add root:paths, a read-only check of what root runs from the tree (fb55ec88)
- feat(ministra): keep a box's token until get_profile has verified the new one (c51513ab)
- feat(admin): keep fields edit_line leaves out, restore the import switches and rate-limit access codes (27b7d145)
- fix(cron): keep a running cron's lock, drop the MySQL login block and enforce the download limit (84e9db3a)
- feat(database): keep panel account names unique, blank old logged values and print why a step failed (02d6cc9c)
- feat(reseller): charge exact prices, sell by the package switches and hold codes nobody redeemed (198c2627)
- feat(streaming): start streams from their stored values, complete source cookies and give utc links six hours (302240aa)
- feat(player): give the web players a session cookie of their own and play radio through the panel (2a70c882)
- feat(auth): block an address that tries many passwords for one username (10a4707c)
- fix(cron): run the crontab install and the firewall flush with literal commands (abb2432c)
- chore(security): annotate the fixed commands of the crontab and firewall code for Semgrep (cb7c256b)
- refactor(session): check a reseller's enabled status in a statement of its own (3ed03a4f)
- fix(security): mint MAG session tokens from the secure random source and count sign-in terms by SHA-256 (bd0783b3)
- fix(streaming): take a token's connection id only in the form the panel mints (efa75212)
- chore(security): annotate the Semgrep false positives in the catch-up stream scripts (91e3d75a)
- test(modules): keep the JIT out of the module update test's child process (9d58fd6a)
- docs: describe the rules the panel enforces after the fixes (9e73209e)
- chore(i18n): add and translate the messages of the new refusals (820a19da)
- fix(install): verify installer downloads and validate certificate host names (c758b66e)
- fix(modules): skip a module that cannot load and apply its schema steps on every update path (0374b93d)
- fix(core): keep the newest backups, verify what is downloaded and keep values out of the query log (bde28888)
- fix(cron): act on stream lists only when they were read, and flush only the panel's own firewall rules (e0d6f009)
- fix(bouquets): let one writer at a time change a bouquet's lists (94068ada)
- fix(streams): pass stream options to ffmpeg as typed and fill each command in one pass (e66b2bcb)
- fix(admin): ask the right permission on every page, action, table and admin API call (1c54a2b0)
- fix(reseller): make credits atomic and hold resellers to their tree, packages and trials (e551ba21)
- fix(player): keep both web players to the line's own content and escape what they print (99c36026)
- fix(session): start every panel session with the hardened cookie settings (3037539c)
- fix(player): fetch only public addresses and bound the image resizer (2581106f)
- fix(ministra): serve a MAG device only once the portal has verified it (6625ffcf)
- fix(auth): count refused sign-ins on every client entry point (c9f11ec8)
- fix(streaming): check viewer requests, tokens and connection rows at the stream entry points (90855afa)
- fix(cluster): hold the mode 2 rules for flows, credentials and enrolment (50e017c6)
- fix(ministra): send channel and genre fields as strings (27f62c07)
- fix(ministra): restore the player prefix in channel and radio cmd (ce3ad1ff)
- fix(ministra): answer a missing or stale token with "Authorization failed." (4a523927)
- fix(ministra): serve the Stalker API at
/server/load.php directly (b18cf165)
2.6.2-dev.16 (nightly)
Source: Vateron-Media/XC_VM@8a3b295
Nightly build from main. Untested — for test servers only.
Changes since 4a739e9cfaff
- docs(readme): add fanout RAM sizing formula (8a3b295d)
- feat(ondemand): make the Instant Off grace period configurable (88092ffc)
- fix(security): escape quotes in the line and device list views (cb58ad80)
- feat(lines): show notes under the username in line and device lists (34600728)
- fix(vod): read subtitles from shared mounts instead of over HTTP (c588290c)
- docs(cluster): the move to mode 2 and the flows a new node starts with (a00bfe5e)
- feat(cluster): move a node to mode 2 from the page, and wait before dropping credentials (85e631c8)
- feat(cluster): a node says it runs from its own copy and follows a mode change at once (8b8609a5)
- feat(install): switch a freshly installed node's flows on (c487aed6)
- fix(epg): create the listings namespace before the TV Guide engine loads (636217cd)
- fix(cluster): queue a node's stream cache refresh for MAIN (a2f8e70f)
- fix(nginx): keep the CORS header on X-Accel hand-offs (7d215b52)
- fix(admin): run the Import & Review import before any output (10e0adb4)
2.6.2-dev.15 (nightly)
Source: Vateron-Media/XC_VM@4a739e9
Nightly build from main. Untested — for test servers only.
Changes since 717409325e15
- docs(streams): add a user guide for custom ffmpeg commands (4a739e9c)
- feat(streams): expose the custom ffmpeg command in the stream form (512bc42b)
- fix(streams): drop empty ids from mass-edit selections (cd2bd10a)
- chore(github): remove the pull request template (98b9abc4)
- ci: skip the quality gate for non-code changes (ba02da8f)
- ci: skip the quality gate for non-code changes (8f4c55a4)
- ci(contributors): render round avatars in the contributors table (eb2ad596)
- fix(ci): give the release and nightly test gates their MariaDB (2e4edbef)
- Prepare release 2.6.1 (7e6f5760)
- fix(make): download dev-php installers into a private temp dir (991c1db8)
- build(make): install composer in dev-php when missing (547edcd0)
- test: keep the suite's output to PHPUnit's own (b0e73d47)
- docs: rewrite the unit-test guide for MariaDB and fix the release checklist (69837a4c)
- chore(repo): drop .gitattributes (b7cdd32a)
- test: run the unit suite on MariaDB only, and on the panel's own stack (9e118da9)
- fix(cluster): hold an HMAC identity whole in cluster_reservations (c5c2abf2)
- ci: run the static analysis on PHP 8.1, the minimum the panel supports (583a0878)
- fix(cli): refuse a truncated migration dump copy (28aa1cd8)
- fix(cli): restore
tools migrationbackups into xc_vm_migrate only (be6dde01) - fix(cron): skip loopback when auto-detecting MAIN server_ip (34ad039e)
- deps: bump phpstan/phpstan in /src in the composer group (859f3d24)
- fix: address the Semgrep findings on the import and recording code (0de1687d)
- docs(modules): document requires_core and its effect (0ac6f088)
- feat(modules): enforce requires_core when loading, installing and updating (be115bd0)
- refactor(stream): move the watch-folder helpers to the watch module (2c0cbf2d)
- refactor: drop the Plex module from core (83668d31)
- refactor(api): let modules register Admin API actions; drop Watch from core (55a10a83)
- feat(vod): run Movies/Series imports as one bounded batch (c4ec6521)
- feat(vod): own the TMDb genre mapping in core (b8705f7c)
- refactor(vod): decode vod_import_item payloads in VodItemImporter (a2055613)
- fix(stream): ignore server-owned columns when scheduling a recording (53b1ad0e)
- feat(stream): own DVR recordings in core (48414c9e)
- docs: document vod_import_item and the core import worker (32dd0784)
- feat(vod): move the per-file VOD importer into core (8f6e3ab2)
2.6.1-dev.14 (nightly)
Source: Vateron-Media/XC_VM@7174093
Nightly build from main. Untested — for test servers only.
Changes since b1001bb3a3c9
- fix(connections): MAIN's close of an ended row never waits for its lock (bc42fe7c)
- fix(connections): a player that opens again on another node is counted (c4ddc267)
- feat(install): a rebuilt node's saved SSH host key can be forgotten (d2657667)
- fix(install): what sysctl -p refuses is said, and the sysctl marker is checked (ce0a2a40)
- fix(connections): only a node in mode 2 skips the closed-row cleanup (a292a69f)
- fix(admin): remove two voucher routes whose handlers never existed (26729d5f)
- fix(ondemand): only a stream's own monitor and producer are killed (69de1054)
- fix(streams): the admin preview of a natively remuxed stream (b7ec5c3e)
- fix(connections): an HLS viewer on a node whose agent holds its viewers (39528004)
- fix(rtmp): a load balancer refuses a viewer it cannot check (2df9ff51)
- fix(servers): a new server whose address is already in use is refused (1d8e06fa)
- fix(install): a load balancer install checks what it needs first (52c921e7)
- fix(install): a ramdisk mount is not glued to an fstab that ends without a newline (4267c331)
- fix(install): the ramdisk mounts and a requested sysctl.conf are checked, not assumed (3c0650ad)
- chore: remove CONTEXT.md and DEAD_CODE.md (d0771499)
- fix(i18n): keep English when a translation reply stops early (80e53c1c)
- docs(agents): bring CLAUDE.md and the subagents in line with the code (bff2b735)
- fix(install): what root runs or unpacks on the node goes through a private directory (9763222e)
- fix(install): a load balancer install stops when xcvm_core is not installed (d94541ff)
- fix(install): file transfers are checked with SHA-256; a script MAIN cannot send says so (2f38dbd4)
- fix(update): a load balancer stays listed until it runs MAIN's release (b0a99a08)
- fix(update): a rolled-back load balancer stays put; the sweep keeps state (1e51b146)
- fix(install): MAIN keeps the installers it sends load balancers current (89733b1a)
- fix(install): load balancers install and update MAIN's release from GitHub (e20772b3)
- fix(cluster): the API no longer answers STARTING every 11 minutes (cc1be0f1)
- fix(status): run its other commands without a shell (7ebca40f)
- fix(status): set the panel's file permissions without a shell (b89aa530)
- test(e2e): lb-hls-kill waits for MAIN to send the player to the load balancer (964f24b8)
- fix(nginx): no thread pool; workers no longer abort when they exit (9c3db348)
- fix: viewer APIs on load balancers, debug-mode statuses, nginx reload bursts (cf26938b)
- chore(tools): take the support bot out of this branch (9bfb57b8)
- fix(connections): a killed HLS viewer on another server stops getting segments (75d2def4)
- fix: errors the test panel logged in its own error log (5b04761a)
- fix(tools): the support bot answers through the admin panel only (7198ea13)
- fix(tools): the support bot defaults to gpt-oss-120b and writes plain text (cc477c50)
- feat(tools): the support bot answers with a free cloud model by default (138b40a1)
- feat(tools): a Telegram support bot that answers from the docs with Claude (9159bf55)
2.6.1-dev.13 (nightly)
Source: Vateron-Media/XC_VM@b1001bb
Nightly build from main. Untested — for test servers only.
Changes since 5f93e5e3e0d7
- docs: MAIN and load balancers, the new cluster, for users (7ab6a521)
- fix(admin): show chart tooltips in local time, not UTC (ec07a2a5)
- Prepare release 2.6.0 (1fe64ae3)
- style: phpcs fixes and the ffprobe cache key's semgrep note (cf7f5ae7)
- Remove redundant comments in CacheEngineCronJob (ecb84d4e)
- Refactor CacheEngineCronJob to remove rPID (7f44c369)
- fix(lines): unpair all paired lines on bulk delete (d0f77df3)
- fix(cache): atomic cache writes and safer stream/line/series regeneration (e49af194)
- fix(fanout): hand the daemon the stream proxy as host:port (48ad3701)
- fix(tools): run the Proxy Checker's ffprobe without a shell (ecc288fd)
- feat(tools): Proxy Checker page to check proxies in bulk for YouTube (2a70b248)
- fix(streams): run yt-dlp and the check-stream ffprobe without a shell (26725686)
- docs: how to restream YouTube (028d7520)
- fix(streams): resolve and fetch YouTube sources through the stream's proxy (f651b4cf)
2.5.4-dev.9 (nightly)
Source: Vateron-Media/XC_VM@99d8711
Nightly build from main. Untested — for test servers only.
Changes since 6e2f19cc03af
- fix(lb-install): take the node's install_id from the last output line (99d87112)
- feat(cluster): badge a node's lane lag and the MAIN URLs it cannot reach (4b3ecd80)
- feat(cluster): a connection-divergence badge and the Settings Info-tab block (543bbadc)
2.5.4-dev.7 (nightly)
Source: Vateron-Media/XC_VM@6e2f19c
Nightly build from main. Untested — for test servers only.
Changes since fc6cb38fa15b
- fix(security): verify_host checks hosts on a node that reads no database (a2e46790)
- fix(cluster): measure a node's own clock, badge its skew, banner the dashboard (502ccfd2)
- feat(cluster): prune servers_stats in batches, and index it online (1517849e)
- feat(cluster): a P0 sequence that goes backwards quarantines the node (b119100d)
- feat(cluster): a new licence key rotates every node's token (74a8221e)
- fix(security): start the updater from an argv list, not a shell line (62f23401)
- refactor(cluster): remove members nothing uses (c544b4bd)
- feat(cluster): route no new viewer to a node about to fence for want of a licence (0f855965)
- feat(cluster): a node updates to MAIN's release, not the newest (591336ea)
- fix(security): verify_host checks hosts again (edb5b9ce)
- fix(cluster): deleting a server revokes its cluster node (afcd7074)
- feat(cluster): a node in mode 2 can be updated, and runs status (860f4f73)
- test(cluster): MainDataPlaneTest's node is never this process (59ea2046)
- fix(cluster): cron:servers sends a mode 2 node's inventory (7396235f)
- refactor(cluster): one archive check and one config.changed predicate (5e1bc6d2)
- chore(stream): mark the RTMP connection id's md5 as not cryptographic (2b83dbca)
- feat(cluster): a section too large for one reply goes to the node in 4 MiB parts (2f45c506)
- test(cluster): the pool gate still precedes the entry point's database handle (8bf65072)
- feat(cluster): a node pulling a module archive with getFile checks its size and SHA-256 (4911b983)
- test(cluster): the extension integration test covers every command type again (e317984d)
- docs(adr): xc_cluster_sim moves MAIN's clock (a5a9b231)
- feat(cluster): a node counts its streams' viewers in one agent call (05f8759f)
- feat(cluster): admit an RTMP viewer of a limited line through the agent (6ff724e9)
- feat(cluster): the cluster API opens MySQL only for an op that queries it (02b8c55c)
- fix(i18n): write language files and the cache in place again (fc475a65)
- build(docs): rebuild the docs venv on a python or requirements change (3d3011c0)
- fix(auth): drop a panel session whose user no longer exists (0a16dc0a)
- chore(i18n): translate panel language files to the current en.ini (c116920a)
- feat(cluster): cluster:reenrol --pending takes only the nodes not on the current root (5069ed10)
- feat(cluster): listen on IPv6 too on the cluster API's own ports (5ce5ef60)
- docs(adr): a failing agent on a node and a canary, MAIN's own reads in the digest report (624aae99)
- feat(cluster): MAIN's own file reads join the N-1 digest report and switch (94b98bf3)
- feat(cluster): roll a failing agent back on the node, and hold a rollout on a canary (442b1df5)
- docs(adr): producers under a fence, MAIN's writes to a node's streams, cache jobs without a licence (ec7db3da)
- feat(cluster): send cache removals as node.purge, which signs without a licence (bc72e365)
- Update readme (6d037bf1)
- feat(cluster): stream.assign and queue.poke, MAIN's writes to a node's streams (9dada292)
- feat(cluster): wake a node when its streams section changes (e0c3643d)
- feat(cluster): a fenced node releases its producers (995f70d5)
- docs(adr): record xc_cluster_sim (5c83db84)
- docs(adr): re-licensing a fleet, the N-1 digest report and switching a cluster setting off (bf29a591)
- feat(cluster): report the owners whose chunk digest names no request (38951bc6)
- fix(settings): let the Settings page switch lb_lease_fence off (324e603b)
- test(e2e): do not wait on the unroute after a form submit (cd550bc8)
- docs(e2e): say which Node versions the suite runs on (b4635cf7)
- test(e2e): look for the Cluster Nodes page title, not its card of the same name (05d9ea8a)
- test(e2e): cover member groups, transcoding profiles, RTMP IPs, HMAC keys and the cluster pages (c45aeabe)
- docs(adr): record the chunk digest's nonce in ADR 0004 (677f73aa)
- fix(cluster): bind a file chunk's digest to the request it answers (8828d926)
- docs(adr): say the Phase 8 fleet acceptance was planned, not measured (573e6937)
- docs(adr): record the MITM harness in ADR 0004 (51c03e3d)
2.5.4-dev.6 (nightly)
Source: Vateron-Media/XC_VM@fc6cb38
Nightly build from main. Untested — for test servers only.
Changes since b489c13a2477
- docs(cluster): say plainly which nodes cluster:rotate-db-password leaves by hand (e96d263a)
- docs(cluster): MAIN's data-plane client in ADR 0004 and the Limits (d1282176)
- feat(cluster): a data-plane client of MAIN's own (cluster:main-dataplane) (258be636)
- docs(cluster): the agent drops the fanout's viewers under a lease fence (7f9bde8d)
- feat(cluster): keep a node's report that its relay proxy cannot bind its port (b68adaea)
- feat(cluster): keep a credential-free node credential-free through reinstalls and grants (941499cb)
- fix(status): point a load balancer's Redis at MAIN's address, not a URL (5826182a)
- docs(cluster): the DB password rotation has one command and travels sealed (0cece500)
- refactor(cluster): one DB password rotation, sealed to each node's box key (c5c24d98)
- docs(cluster): core pins, the credential strip and the DB password rotation (70ccd83e)
- feat(cluster): rotate the panel's DB password through xcvm_core (8a370655)
- feat(cluster): operator actions to pin a node's core and drop its DB credentials (8db91384)
- feat(cluster): pin MAIN's panel key in every node's xcvm_core (core.pin) (1b2f522b)
- docs(adr): record Phase 9's compiled lease verdict and credential actions (1877c6dd)
- feat(cluster): NodeLease consults xcvm_core's compiled lease verdict (09e95259)
- feat(cluster): node.root strip_db_credentials / install_config and MAIN's revoke (03b74feb)
- docs(adr): 0004 records Phase 9's commands, rotations and lockdown (fc10c768)
- test(cluster): the stream-secret rotation may re-encrypt stored data (919bf0cb)
- feat(cluster): install a new LB in API mode without a DB grant (fd524af6)
- feat(cluster): node.root rotate_sign_key re-pins MAIN's key without SSH (9a758b9f)
- feat(cluster): cluster:lockdown and --undo, manual only (ed8836ce)
- feat(cluster): rotate the Redis and DB passwords for the nodes that use them (655fc0a6)
- feat(cluster): cluster:rotate-stream-secret, resumable, re-encrypting stored data (36bd3951)
- feat(cluster): send the restrictive commands nothing produced (f4a2bedc)
- fix(i18n): add dashboard_nav_top, sub_reseller and system_template to en.ini (af42d743)
- docs(adr): 0004 records the agent's lease_state.json and MAIN clock (04b918d1)
- test(cluster): judge the agent's own lease_state.json in NodeLeaseTest (7abc62d6)
- feat(admin): Cluster Nodes fence windows, banners, figures and rotate-all (46795172)
- feat(cluster): ClusterLicenceLapsedEvent when a lease is refused for the licence (63e4ba9a)
- feat(cluster): server:diagnose reports a node's cluster state (3e322241)
- chore(i18n): drop keys en.ini no longer has from the other language files (0839df76)
- docs(cluster): the lease fence is built behind lb_lease_fence; two update rules (c970c5f1)
- fix(cluster): serve /xfile with nosniff and annotate the Semgrep false positive (64bdc723)
- fix(cluster): harden the data plane after security review (90641d9c)
- feat(cluster): the data plane without bearer credentials (Phase 8 relay half) (be87b8c2)
- docs(adr): record the fanout switch, supersede P4 and the CLOCK_SKEW resync (b392fa6e)
- feat(admin): quick search renders the full JSON contract (8445e225)
- fix(streaming): fanout_enabled=0 fully restores the pre-fanout path (573d7120)
- fix(nginx): MAIN's own /api keeps no toggle (ADR 0004, Phase 8) (5d607c16)
- fix(cluster): mode 2 needs root's pin in place, as ADR 0004 requires (065239c5)
- fix(modules): validate a stream form tab only when its fields were posted (836ed706)
- fix(auth): refuse post.php save actions that no rule covers (bd860333)
- docs(modules): drop stream middleware; list the events core actually dispatches (edfda263)
- refactor(modules): remove the stream middleware pipeline that never ran (418c7067)
- fix(install): name the LB installer's temp files with random_bytes, not md5(time()) (41f6d11e)
- refactor(modules): split the tab validator call out of StreamFormRegistry::validate (77cf2c03)
- refactor(cluster): agent paths, signed-token encoding and php-fpm pools written once (0a75e890)
- refactor(cluster): enum settings, policy version, enrolment start and CLI helpers written once (e6b62341)
- refactor(cluster): one reader for a stored stream record and for ids in file names (a530d6e2)
- refactor(cluster): one connection uuid pattern, identity rule, route and reservation helper (9cb5f053)
- docs(modules): import kinds (02b49fe8)
- feat(modules): module import kinds on Import & Review (c4843954)
- fix(streams): Stream Review saves EPG alone again (e943d624)
- fix(streams): Import & Review writes only stream columns (6b6e8a23)
- docs(modules): stream form tabs and StreamSavedEvent (b4da1f83)
- feat(modules): stream form tabs and StreamSavedEvent (7a054b8f)
- fix(i18n): lang-translate saves every key as it goes and skips engines that lack the language (ba719fbe)
- docs(streams): source drivers are validated on save; add the domain glossary (e96e3f6d)
- feat(streams): driver sources answer source checks and supervisor probes (6619b957)
- feat(streams): refuse stream saves that hand a driver URL to anything but its engine (dd38b375)
- fix(streams): never refuse a scheme a bundled ffmpeg reads (a072ddbb)
- refactor(cluster): share constants, test seams, audit days, base32 and install base (969595f2)
- refactor(cluster): write files atomically through one Core helper (215d41dc)
- refactor(cluster): one connection identity rule and one stored-connection reader (3767819e)
- refactor(stream): one helper picks and redacts a stream's state fields (b0115c49)
- refactor(cluster): one copy of the queue SQL and the strict read (37182613)
- refactor(cluster): write the endpoint's request checks once (ccede63f)
- refactor(cluster): read every clamped cluster setting through ClusterSettings::int() (835448b8)
- fix(cluster): end the CLI's id and fingerprint checks in \z too (6bf7186d)
- docs(adr): command registry, endpoint fixes and corrected status lines (a029916b)
- test(cluster): fix the arch fixture and SERVER_ID order dependence; cite real tests (d6f0bd73)
- fix(admin): a stored cluster_offline_after_sec of 0 means 30 s on the Cluster Nodes page too (6873a20d)
- fix(auth): point access code type 5 at the Ministra portal in core (2b3d602d)
- fix(lb): honour api_legacy.conf on load balancers (a9a72f28)
- fix(install): write root-owned files over SSH with sudo tee; fix the ramdisk toggle (71b348eb)
- fix(cluster): a failed write keeps the event batch and its cursor unapplied (dcd3df90)
- fix(cluster): harden the API endpoint against races, replays and bad records (2ca86fd2)
- fix(cluster): send commands the extension signs, and never lose one silently (0f260b8c)
- docs(contributors): update contributors list (2cc1a829)
2.5.4-dev.5 (nightly)
Source: Vateron-Media/XC_VM@b489c13
Nightly build from main. Untested — for test servers only.
Changes since ebd7576b9e1e
- fix(cluster): the bus's block must not be a fraction on an older phpredis (b6428fa7)
- docs(adr): what the fence's drain actually drains (014847de)
- feat(cluster): a node stops serving when its lease runs out, behind a switch (201aaaa0)
- docs(adr): the anchor on MAIN's clock the node now keeps (211847fa)
- docs(adr): which key verifies a lease, and what provisioning each choice needs (58a59b5d)
- docs(adr): the node keeps the lease, and what its enforcement may not assume (609f2f6f)
- feat(cluster): every token a node is handed carries its lease (0943627e)
- docs(adr): the status line names the phase-8 and phase-9 increments that landed (04ed21df)
- i18n: the cluster and dashboard keys in the seven other languages (583109b5)
- fix(ci): what phpcs, PHPStan and the test database caught on main (7e02443b)
- Update tests/Unit/ProcessRunnerTest.php (2497edd6)
- fix(security): launch the three background commands without a shell line (6a75d8a4)
- docs(modules): source drivers guide for module authors (37f88119)
- feat(cluster): ask the agent for the data plane's nonce window and digests (f70c22fa)
- feat(streams): source drivers — module-owned live sources with their own producer (ac2ad9fd)
- feat(cluster): give the legacy /api its own switch (680acedb)
- feat(cluster): show the cluster on the dashboard and the servers list (dce55b59)
- feat(cluster): let an operator rotate a node's token on request (515e5663)
- docs(cluster): the cluster API's protocol and operator guide (a2de2c2e)
- feat(cluster): carry the fleet's heartbeat in the transport policy (7b4c9084)
- feat(cluster): accept a token minted under the replaced viewer secret (2de2a6ca)
- test: fix proc_close exit code on PHP < 8.3 and isolate StreamRuntime store (154660a9)
- fix(cluster): one boot sequence, a disabled line's sessions, and dead settings (bb8e8981)
- fix(cluster): keep the daemons in one process instead of re-execing each pass (5914d8a7)
- ci(cluster): gate the crypto vectors and Core's reach into MAIN's domain (a5e97ecb)
- feat(cluster): let an operator require HTTPS, and prune what the settings say (95578251)
- feat(cluster): offer every node the agent version MAIN pinned (a1f7e2b3)
- feat(cluster): report a node's on-demand checks and closes over the API (01ba5c32)
- feat(cluster): keep a node's activity, status and reconciler off MAIN's database (230b601f)
- feat(cluster): serve a node's encoding queue over the API (ccd0a1c4)
- fix(cluster): stop fleet-wide jobs treating every node as MAIN (e6133297)
- feat(cluster): promote and demote a node's mode behind the cutover gate (52212ef7)
- feat(cluster): let an operator switch the CONFIG flow (71b6503c)
- docs(cluster): record the node system API's own inputs (a9eaf1d2)
- fix(security): confine the node system API's paths, probe targets and pids (0807d07a)
- docs(cluster): record the cache jobs and reloads without a shell (45de9bae)
- fix(security): run cache jobs, nginx reloads and flush without a shell (726637eb)
- docs(cluster): mark the agent's R2 and catalogue halves built (4ac672cb)
- fix(cluster): address the node's own store of its streams' state review (f7ce00bf)
- docs(cluster): record the node's own store of its streams' state (0e74684d)
- feat(cluster): read this node's streams from its replica and store (52e7cbf2)
- feat(cluster): keep the node's streams' runtime state in its own store (408e7492)
- fix(cluster): address the mode 2 signals daemon and cron:certbot review (8ccecc2c)
- docs(cluster): record the signals daemon and cron:certbot in mode 2 (32499953)
- feat(cluster): keep cron:certbot and certbot off MAIN's DB in mode 2 (66fe7ba6)
- feat(cluster): send a mode 2 node's cache jobs as node.cache commands (2bc74bce)
- chore(install): drop Debian 11 support (05470de9)
- chore(install): mark Debian 11 as EOL (06af366a)
- fix(security): test root's commands on full pipes and exit status (b9a8fd75)
- docs(cluster): record root's commands without a shell (bd110538)
- fix(security): run the artefact and module commands without a shell (647a1b05)
- deps: bump phpstan/phpstan in /src in the composer group (4bab1fd1)
- ci(security): drop nosemgrep-suppressed findings before SARIF upload (4de3d411)
- build: add make semgrep target mirroring the CI security scan (32583beb)
- docs(cluster): mark the agent contracts xc_vm_fanout has built (2258de05)
- fix(cluster): address the artefact op review (bf07fe2e)
- fix(cluster): let an acked command give up its dedupe key (c6cdbb45)
- fix(cluster): close root's artefact stage when it finds it open (7b46c5ce)
- docs(cluster): record the artefact op and its hash-checked staging (1f380bec)
- feat(cluster): grant artefacts and serve them through the artefact op (255b1cec)
- feat(cluster): stage and hash-check artefacts on the node (216012fa)
- docs(cluster): number the R2 node increment and order Phase 7 notes (3aaf80bd)
- fix(cluster): address the R2 streams section on the node review (3f20854e)
- docs(cluster): record the R2 streams section on the node (2315542f)
- fix(cluster): keep unverified stream records out of the node's caches (7749f27e)
- feat(cluster): replicate the bouquets and categories caches (c7fd1efd)
- feat(cluster): apply the R2 streams section to the node's stream caches (c25fe5b6)
- refactor(cluster): share the stream record reads with the node (3ebdb61c)
- fix(cluster): address the mode 1 replica boot review (7330648b)
- docs(cluster): record mode 1 booting from its replica (54a544a7)
- feat(cluster): boot a mode 1 node from its replica once CONFIG is on (1a784658)
- fix(cluster): address the mode 2 paths review (fbd295dc)
- docs(cluster): record the mode 2 paths moved off MAIN's database (4f00b147)
- feat(cluster): keep the watchdog, cleanup and shadow apply off MAIN (65a797c9)
- feat(cluster): run cron:root_signals from the replica in mode 2 (b4e90dea)
- feat(cluster): send root's system log lines through the agent (37dc48c7)
- fix(cluster): address the R2 streams section review (eca61b78)
- docs(cluster): record the R2 streams section on MAIN (d72b3b9b)
- feat(cluster): read the node's stored R2 streams section in PHP (f2782ce8)
- feat(cluster): serve the R2 streams section through the streams op (0f5d8632)
- feat(cluster): stamp each stream's R2 version at MAIN's config writers (7d7b0148)
- fix(cluster): address the bus authentication review (f4ace25b)
- docs(cluster): record authentication on the cluster bus (59da0c7c)
- perf(cluster): read MAIN's server row only for the ops that use it (86415329)
- feat(cluster): authenticate cluster requests from the cluster bus (b0a54822)
- refactor(cluster): share the bus marks through ClusterBus (1fdf1607)
- fix(cluster): address the settings-side endpoint change review (0e1936c2)
- docs(cluster): record the settings-side endpoint changes (fc561a00)
- fix(cluster): merge endpoint changes stored at the same moment (0a02361b)
- feat(cluster): keep the old URLs after a settings-side endpoint change (d8dac321)
- fix(cluster): address the mode-2 refusal and connect audit review (3e8a2957)
- docs(cluster): record the mode-2 refusal and the connect audit (819bd1e6)
- fix(cluster): run the blocklist flush from a node.root command (dea6f3fa)
- feat(cluster): keep each node's connect counters and show them (e59bc8bc)
- feat(cluster): refuse MAIN's database and Redis on a node in mode 2 (47d275f6)
- feat(cluster): count every connect to MAIN in modes 1 and 2, bounded (f38d4266)
- fix(cluster): address the ReplicaStage and settings-miss review (5087631b)
- docs(cluster): record ReplicaStage, boot from disk and settings misses (32455581)
- feat(cluster): report settings reads the replica would not answer (4566ecbd)
- feat(cluster): boot from the node replica with ReplicaStage (fd5ac539)
- feat(cluster): verify the stored replica for cluster:apply --from-disk (bbcd3617)
- fix(cluster): keep an old port for enrolments, https_required and mode 0 (c3c0d30d)
- docs(cluster): record the early release of old MAIN ports (335db219)
- feat(cluster): release an old port once every node uses the new URL (8a5e7ef0)
- feat(cluster): record the policy and MAIN port each node uses (c2eb84d6)
- fix(cluster): keep MAIN's old URLs only where nginx served them (cc1dcb2a)
- fix(cluster): keep serving an old HTTPS port while an API port is staged (a112e2fb)
- docs(cluster): record the announced HTTPS port and address changes (0a79eeaa)
- feat(cluster): announce MAIN's HTTPS port and address changes (80123771)
- fix(cluster): never sign a replica section built from a failed read (6872ca54)
- docs(cluster): record the secrets section and authoritative settings (33623fc4)
- feat(cluster): make the settings and secrets sections authoritative (d28d6af3)
- feat(cluster): serve the sealed secrets section of the node replica (8f0fd0ce)
- fix(cluster): keep one ingest permit for bulk, and one VOD per recording (cc84f1e2)
- docs(cluster): record the ingest permits on the cluster bus (c893a1dd)
- feat(cluster): take ingest permits on the bus, with a P0 reserve (7fb213e6)
- fix(cluster): ask again for a recording's VOD while MAIN is busy (ab3d7f9d)
- chore(security): annotate Semgrep false positives with nosemgrep (ce0cecec)
- fix(auth): verify TLS when calling reCAPTCHA siteverify (f70d509f)