Every stream link, HLS key URL and admin preview token is minted under
live_streaming_pass, and the links are already in players' hands when the
secret changes: the token a viewer sends next was minted under the old value.
Changing the secret — which the settings form has always allowed — therefore
broke every live link at once, so a leaked secret could not be rotated without
an outage. The replica's `secrets` section already carried
{kid, current, previous, previous_valid_until} for exactly this, with the
previous half hard-coded to null.
StreamSecret keeps the value replaced beside the config (0600, as OPENSSL_EXTRA
keeps its own) and readToken() tries it once the current secret fails, for the
sealed and legacy formats alike. MAIN writes it when a settings save changes
the value, ReplicaBuilder publishes it, and a node adopts what MAIN dated and
never invents one of its own. The file is stat-ed on each read rather than
cached for the process's life, because the php-fpm worker that reads a viewer's
token is not the process that replaced the secret.
A `log.*` event is bounded in bytes as well as rows now: a caller's batch is
bounded in rows while a row is as long as its source made it, so a thousand
oversized rows were one event of tens of megabytes to redact, serialise and
post — more than MAIN's ingest takes, and more than the import survived. The
unit suite declares its memory limit for the same reason: a run that crossed
PHP's 128M default died with a bare exit 255, the message swallowed by
PHPUnit's per-test output buffer, and the class that reaches megabyte rows
already sat at 101M on its own.
Move the .ini language files from src/resources/langs/ to
src/Core/Localization/lang/, next to the Translator subsystem that owns
them — which already defaulted its $langsDir to __DIR__ . '/lang/'. This
dissolves the now-vestigial src/resources/ bucket (its data/ tree went
with admin_constants, libs/ was empty).
- bootstrap.php calls Translator::init() with no argument, relying on the
class's own __DIR__-relative default instead of MAIN_HOME . 'resources/langs/'.
- Makefile LB removal list points at Core/Localization/lang (and drops the
gone resources/langs, resources/libs); LB still ships no UI translations.
- Drop the stale src/resources entries from phpstan scanDirectories and the
phpunit coverage excludes.
- Update the English docs (translations guide, build-system table); the ru
tree is regenerated before release.
- add PHPUnit bootstrap and config under tests/
- add focused unit tests for GitHubReleases, InputValidator and FfmpegPaths
- fix GitHubReleases cache file handling when switching update channel
- document PHPUnit PHAR usage and debug run commands in RU/EN docs
- document SFTP sync for tests/ and contributor test workflow
- remove broad smoke coverage approach in favor of per-file tests