Drop the two ministra restoration working-notes now that the work is
done: ministra-unused-modules.md (dead-module audit complete) and
ministra-5.6.10-lost-customizations.md (all items resolved). Also drop
the now-dangling doc reference from the get_modules debug comment.
The ministra-browser-emulation.md integration guide is kept.
Review of the remaining 5.6.10 lost-customization items:
- player.js: multi-audio (titles/infoCurtitle) kept and improved by
5.6.10; xc_vm PVR branch intact; parental flow lives in tv.js, not
here. No changes needed.
- account.js: keep the full 5.6.10 account screen (decision) instead of
restoring the minimal Phone+message fork screen.
- xpcom.common.js: allowed_stb_types/aurahd richer in 5.6.10;
outdated_firmware (player<1382) only gates non-whitelisted types and
is more permissive, not a regression; check_image_version is a no-op
(backend sends no autoupdate); load_channels parental left to 5.6.10 +
tv.js guards to avoid a double password prompt.
Re-apply two xc_vm customizations that the 5.6.10 client drop wiped out:
- Channel logos (tv.js handling_block + player.js preview): on xc_vm the
backend sends a ready-to-use logo URL, but 5.6.10 rebuilt a classic
stalker misc/logos/<size>/ path, breaking the image. Use the URL
directly; keep the 5.6.10 timeshift_mode class on the player logo.
- TV color buttons (tv.js): in the xc_vm theme the 4th button is channel
search (search_menu_switcher) instead of the fav-manage "move" mode.
Hybrid with the new 5.6.10 quality-filter button — quality wins when
the profile enables tv_quality_filter, otherwise search.
Also drop the obsolete snumber/sortIDs note: the backend now numbers
channels sequentially, so 5.6.10 sortBy("number") is correct.
- Add ministra-5.6.10-lost-customizations.md: what our fork's clean
5.6.10 drop wiped out and how to restore it (get_types_list, tv.js
parental control, channel logos, account screen, DVR .ts format, ...).
- Update ministra-browser-emulation.md for the ?debug_key gate.
Drop portal JS modules that the loader never pulls in (not in
base_modules/all_modules, no dynamic loader, no live references) and
their theme assets:
- infoportal branch: infoportal, anecdote, cityinfo, horoscope,
weather.current, weather.day, course.cbr, course.nbu, game.mastermind
(root module dead + crashes main menu when force-enabled)
- magiccast (leaked proxy creds to an external Infomir service)
- youtube (web wrapper dir absent from repo)
- demo, service_management (stub features, no server handlers)
- karaoke (no backend; "radio only")
- pvr.js (legacy Pvr, never instantiated; live local PVR is
pvr_local/records)
- JsHttpRequest-debug.js (core loads JsHttpRequest.js)
Removes 15 per-theme CSS variants + menu icons per module. The dead-code
audit is tracked in docs/ru/guides/ministra-unused-modules.md.
Add an entry (RU + EN) explaining why a MAG/STB box gets its IP blocked
after a factory reset / firmware change: the portal's MAGSCAN anti-clone
check compares the posted serial against the stored mag_devices.sn (and
device_id/device_id2/hw_version when lock_device is on) and bans the IP on
mismatch (blocked_ips -> iptables). Documents the fix — reset the device's
stored sn/device_id in the panel — and how to unblock: the web panel
(Tools -> IP Management, /<admin-code>/ips), console.php tools flush, or
manual iptables + flood-marker removal.
Ministra stops being a module — the whole Stalker portal (portal.php,
MinistraBootstrap, PortalHandler/PortalHelpers and the STB front-end) now
lives in src/Ministra/ under the XcVm\Ministra namespace, served at
/home/xc_vm/Ministra via the nginx alias.
- src/ministra/* and Modules/ministra_85a7d/{PortalHandler,PortalHelpers}
→ src/Ministra/; MinistraModule.php + module.json removed. Ministra was
the only committed module, so src/Modules/ keeps a .gitkeep.
- portal.php resolves PortalHandler as a sibling and derives MAIN_HOME from
its new location (glob crutch gone).
- nginx alias + AuthRepository $rAlias switched to /home/xc_vm/Ministra
(PascalCase); ministra entry dropped from bundled_modules.php.
- Makefile: Modules/ removed from LB_DIRS — all modules are MAIN-only, so
the ~50 MB of portal assets no longer ship to LB nodes.
- ArchitectureTest: zero committed modules is now a valid state.
- PHPStan: analyse src/Ministra, exclude the procedural portal.php entry,
repath the ministra baseline entries.
- Docs (architecture, ministra-browser-emulation, extraction plan) updated
to the new layout; the "extract to a separate repo" plan is cancelled.
Verified: php -l, make gates, make phpstan (No errors), full unit suite
(432 tests). On-server smoke: handshake + get_profile work end-to-end with
a registered MAC after deploy.
BoundaryInterface was a marker interface with no runtime consumer —
nothing read getEntryPoint()/isIsolated() and, being static-less
metadata, it enforced nothing. Its only implementor was MinistraModule.
Removes the interface, drops `implements BoundaryInterface` plus the two
orphaned methods from MinistraModule (getName/getVersion stay — they come
from BaseModule/ModuleInterface), and deletes the now-empty Core/Boundary/.
Test contract (InterfaceContractTest) loses the three BoundaryInterface
assertions; docs (en/ru architecture + modules, .github instructions) now
describe isolated subsystems like Ministra as a convention — own entry
point + bootstrap — rather than a marker interface.
Verified: php -l, make gates, make phpstan (No errors);
InterfaceContractTest + ArchitectureTest green (33 tests, 96 assertions).
The script was never wired up (no `make module-hashes` target, no CI/Makefile
caller). Module hash_id generation now lives in the standalone Module_Template
kit; for existing modules, generate inline with
`php -r 'echo bin2hex(random_bytes(16));'`.
Updated the module-dev docs (en + ru) that referenced the removed script /
non-existent `make module-hashes` target to use the one-liner.
Standalone Python (stdlib-only) tool that verifies a stream delivers
segments correctly and its delivery queue does not break:
- HLS: EXT-X-MEDIA-SEQUENCE contiguity, no dropped/rewound segments, no
EXT-X-DISCONTINUITY, every newly appearing segment downloadable.
- MPEG-TS: per-PID continuity_counter, sync-byte loss, TEI, delivery stalls,
with a --tolerance for rare source glitches relayed by -c copy.
- --live: colored TUI dashboard modelling a virtual player — received
timeline from PCR (TS) / EXTINF (HLS), playhead, and buffered cache
seconds graphed over time.
Documented in docs/{en,ru}/development/streaming-subsystem.md.
Per-distro distribution plan updated with what the three deployed
binaries actually are (XUI 2018 / mardock2009 no-GPU / our glibc-2.35
build), the code-driven target codec set (+nvenc/cuvid/librtmp, -AV1),
the 8.1 label decision, and the -nofix_dts custom-flag replacement plan
validated via tools/dts-audio-test.
The heartbeat is written by the watchdog daemon (which now waits out DB
outages), not by cron:servers; the babysitter section documents the
crontab/cron-service/hung-lock sub-checks, and the cheat-sheet covers
the 'all nodes drop at the same moment' scenario. cli-tools blurbs
updated to match (en/ru).
update-system.md and faq.md (ru+en) linked to <lang>/development/cli-tools.md,
but the file lives at <lang>/guides/cli-tools.md (as the sidebar already points) —
the old path rendered an empty docsify page. Also repoint two non-existent anchors
(#миграции-базы-данных, #database-migrations) to the real section
(#обновление-бд-после-обновления-версии / #database-updates-after-version-upgrade).
The plan is done: proxy.tar.gz is fetched from XC_VM_Proxy releases at install and
kept fresh by cron:proxy, and the LFS object is gone. Rationale lives in the commit
history and XC_VM_Proxy/RELEASE.md.
Add a `cron:proxy --force` step to the installer right after `cron:maxmind --force`
(same "no longer bundled — fetch on install" pattern), run as xc_vm and non-fatal,
so a fresh panel downloads proxy.tar.gz and writes proxy_version.json at install time.
Drop the StartupCommand background prefetch — redundant now that install + the daily
cron:proxy + the ServerInstallCommand self-heal cover every path, matching how
cron:maxmind is wired.
proxy.tar.gz is no longer served from Git LFS. A new proxyArchiveUpdater (Core/Proxy, mirrors MaxMindUpdater) downloads it from XC_VM_Proxy GitHub releases,
verifies hashes.md5, publishes atomically into bin/install/ and records a proxy_version.json index. It runs at panel startup (StartupCommand prefetch), on a daily cron:proxy (crontab seed + migration 009), and as a self-heal before proxy-node install (ServerInstallCommand, status=4 on failure). The streaming download primitive is extracted to CurlClient::downloadToFile and reused by ModuleManager. Clean-latest per channel, force-local kill-switch, last-known-good fallback when GitHub is unreachable.
The panel is deeply coupled to TMDb (VOD import, player metadata, admin
search, two crons), so shipping it as an uninstallable module only added
failure modes: after the move to hash-suffixed dirs (tmdb_f4e6e) every
hardcoded `Modules/tmdb/lib/...` require broke, and 2.3.3 crons died with
"Failed opening required TmdbClient.php".
tmdb -> core:
- Vendored \TMDB client -> src/Infrastructure/Tmdb/lib/; the only loader
is TmdbApiService::requireLibrary() (now public, also loads Release.php).
- TmdbApiService -> XcVm\Infrastructure\Tmdb — composer-autoloaded in every
bootstrap context, no module boot required (player scope never booted
modules, so module-namespace classes were unreachable there).
- TmdbCron / TmdbPopularCron -> XcVm\Domain\Vod; cron jobs -> Cli/CronJobs
(picked up by the console.php scan; command names cron:tmdb and
cron:tmdb_popular are unchanged).
- TmdbController -> Public/Controllers/Admin; tmdb_search / tmdb api
actions registered in routes/admin.php (same dispatchApi fallback).
- Domain/Vod services and player_functions.php load the lib through
TMDbService::requireLibrary() instead of hardcoded module paths.
- tmdb removed from config/bundled_modules.php. ModuleLoader gains
CORE_PROVIDED_MODULES: released watch/plex archives still declare
"dependencies": ["tmdb"] — such deps are stripped during manifest
normalization and in ModuleManager::listModules().
- syncBundledModules() purges stale on-disk tmdb module dirs and their
config/modules.php state on upgraded panels, so the old copy cannot boot
alongside the core implementation and collide on command names.
Standard-set provisioning fix (root cause of the "Undefined variable $db"
errors from watch/plex settings views on 2.3.3):
- Production still ran watch_e6c86/plex_20cd9-less legacy copies migrated
from 2.3.2 with generated hash_ids; provisionStandardSet() treated any
same-name directory as "already on disk" and never fetched the pinned
1.0.2/1.0.1 releases that contain the fix. A same-name directory whose
identity does not match the pinned hash_id is now considered stale: it
is deleted and the pinned release is installed in its place.
- installModuleFromSource(): when the module is already recorded as
installed (files re-provisioned over a stale copy), run updateModule()
(incremental from->to migrations) instead of re-running the initial
install.
Document the directory naming convention, the mandatory/auto-generated hash_id,
runtime generation + auto-migration of legacy bare dirs, and the update-source
manifest block, in both EN and RU module guides.
Bundle interactive OpenAPI 3.0 documentation for all XC_VM APIs into the
docsify site and align the docs visual with the Swagger UI page.
API reference
- Add self-contained Swagger UI host page (_media/swagger-ui.html) with a
tab per specification (Admin / System / Player / Playlist) plus nested
Documentation and Swagger views; deep-linkable via ?spec=<key>.
- Add OpenAPI 3.0 specs: admin-api (renamed from openapi.yaml, 104 ops) and
new system-api (31 actions), player-api (XtreamCodes) and playlist-api,
generated from the existing prose guides and controllers.
- Add EN/RU hub page (api/swagger.md) and wire it into the sidebars.
- Remove now-obsolete prose guides (system_api.md, xtreamcodes_api.md,
playlist.md) after verifying full coverage in the specs.
- Rebrand XUI.ONE -> XC_VM across the spec and host page; point links to
github.com/Vateron-Media/XC_VM.
Theming
- Add shared design tokens (_media/theme-tokens.css) consumed by both the
docs and the Swagger page as a single source of truth.
- Switch docsify to docsify-themeable (Simple / Simple Dark) and drop ~150
lines of hand-written CSS.
- Add a light/dark toggle synced across both pages via localStorage['theme'];
default to dark.
`php -l` syntax checking is redundant with the real linters/validators (PHPStan
parses the code, PHP-CS-Fixer and the PHPUnit bootstrap also fail on parse
errors). Remove the script and every reference to it:
- Makefile: drop the `syntax_check` target and its .PHONY entry.
- CI (ci.yml): drop the dedicated `lint` (PHP Syntax Check) job.
- Release workflows (build-release, build_pre-release): drop the "Check syntax"
step from the Quality Gate (PHPUnit remains).
- CONTRIBUTING.md: replace the syntax-check pre-commit guidance with the real
checks (make dev-tools / phpstan / cs / gates / phpunit).
- updates_checklist (en/ru): replace `make syntax_check` with the quality-check
suite and drop the stale "Security scan" snippet that referenced the removed
script and a non-existent tools/run_scan.sh (Semgrep runs automatically in CI).
Overhaul the Docsify documentation (English + Russian) so it matches the current
codebase and follows one consistent pattern.
Content accuracy (post-migration):
- Rewrite development/autoloader.md to PSR-4 / Composer (the old XC_Autoloader
scanner, igbinary tmp/cache/autoload_map and registerDirectories are gone).
- PascalCase every source path (src/core -> src/Core, domain/Stream, cli/Commands,
public/Controllers, Infrastructure/Redis, ...) across all docs.
- Replace the removed autoload.php references with vendor/autoload.php
(build_system, bootstrap-contexts, error-handling, modules).
- ssl-generation: note that the installer now auto-generates a unique self-signed
certificate before Nginx starts.
Common pattern (Clean & uniform):
- Strip emoji from headings; remove the in-page Navigation blocks (the Docsify
sidebar already provides navigation).
- One H1 + intro per doc; uniform "Related files" / "Связанные файлы" section,
added to the code-centric docs that lacked it.
Structure:
- Remove the empty stray docs/api/; move updates_checklist.md into builds/;
link the previously-orphaned ucs-integration.md.
- Regroup the sidebars (split the oversized guides group into Developer Guides /
Security & Access / Integrations; fold builds into Build & Release).
Augment:
- dev-workflow: Local Setup (make dev-tools) + Quality Checks (phpstan, cs, gates).
- build_system: Composer Dependencies section (committed prod-only vendor,
committed lock, dev tools via composer install, no build-time vendor step).
en/ru parity:
- Apply the same structure, fixes and pattern to docs/ru/ (translated), including
a new Russian ucs-integration.md. The en and ru file sets are now identical.
ARCHITECTURE.md and ARCHITECTURE_RU.md (620 lines each) were a parallel
documentation source that drifted from the code and contained outdated
references (CONTEXT_* string constants, global $db, MIGRATION.md which
does not exist).
All relevant content is now covered by specialized pages in docs/:
- Module system → development/modules.md
- Bootstrap contexts → development/bootstrap-contexts.md
- Event system → development/event-system.md
- Build variants → builds/build_system.md
docs/{en,ru}/development/architecture.md rewritten as a clean, self-contained
overview: source tree table, runtime flow diagram, extension points table,
contributor rules. Broken links to ARCHITECTURE.md and MIGRATION.md removed.
Replaced the incorrect BoundaryInterface API (boot/getExportedServices)
with the real contract (getName/getEntryPoint/isIsolated). Updated all
examples to use extends BaseModule instead of implements ModuleInterface.
Both English and Russian guides are in sync.
- Removed ConfigLoader.php and transitioned to using ConfigReader for configuration management.
- Updated DatabaseHandler instantiation to no longer rely on global $_INFO, instead using default parameters.
- Enhanced Database and MigrationRunner classes to improve error handling and connection management.
- Simplified RedisManager connection logic by utilizing XC_VM::redis_connect().
- Adjusted various controllers and services to align with the new configuration and database connection methods.
- Removed unnecessary global variables and improved code readability across multiple files.
- Updated comments and documentation to reflect changes in configuration handling and database connections.
- Implemented `ServerInstallCommand` for installing and configuring servers via SSH.
- Created `ProxyInstallFlow` class to handle proxy-specific installation tasks.
- Updated `ServerService` to use the new command structure for server installations.
- Modified API endpoint to initiate server installations using the new command format.
- Enhanced error handling and logging during installation processes.
Co-authored-by: Copilot <copilot@github.com>
- Added new fields to module.json: environment, dependencies, has_navbar, and has_settings.
- Updated ModuleLoader to support environment filtering and topological sorting of modules based on dependencies.
- Implemented error handling for missing and cyclic dependencies during module loading.
- Enhanced documentation for module.json structure and ModuleLoader functionality.
- Introduced unit tests for ModuleLoader to validate loading behavior and dependency resolution.
- Updated existing modules' manifest files to include new fields.
Co-authored-by: Copilot <copilot@github.com>