Release history
Changelog
Every new feature, fix and speed-up on s&box Explorer, newest first.
- Last 30 days
- 90
- Features shipped
- 233
- Fixes
- 218
- Days with changes
- 66
17 changes in October 2026 Clear filters
October 2026
2
-
Tests
3:32 AM
Make csrf_cors, mcp_security and js_referenced run on Windows
Details
csrf_cors and mcp_security spawned php -S with /dev/null for its output, which does not exist on Windows, so proc_open returned false and proc_terminate threw. They now use NUL there. js_referenced built its git ls-files command with single quotes, which cmd.exe does not understand, so the corpus was empty and every script in frontend/js looked unreferenced. It now uses double quotes.
All three were environment failures, not product bugs, and pass.
20d843c -
Maintenance
1:54 AM
Accept api/list baseline (63 endpoints)
Details
Adds ai/query, ai/chat/create, ai/chat/query (401 without a game session), shader/1/{crc} and package/dll/1/{ident}/{rev} (engine-token binaries). None are usable by the site.
1f62ceb
15
-
Docs
10:30 PM
Rewrite the README against the current code
Details
Corrects PHPStan level (1, not 5), the cache TTL table (from cache-constants.php), the service list (FacepunchApiService, no PackageService) and the test commands (only tests/Unit has Pest tests; the standalone runner and Vitest are documented). Adds data sources, player history, the two kinds of MCP key, the SALT option, the daily session cleanup and the cron jobs, and replaces the fork-and-PR section with the actual closed-source status and house style.
fceaafe -
Tests
6:08 PM
Run under the node environment
Details
Under vitest's jsdom environment on Node 24 the worker's response.blob() returns a Blob that jsdom's Response stringifies, so the offline-cache test failed with a JSON parse error on '[object Blob]'. The worker has no DOM dependency, so the file runs in the node environment.
2da9a7e -
Docs
5:50 PM
Correct the PHPStan note now that there is no CI
65a777e -
Maintenance
5:50 PM
Remove the GitHub Actions workflows and add npm run check
Details
The repository is private and Actions minutes are billed. The checks the workflows ran are unchanged and run locally with npm run check; AUDIT.md records the decision.
46b6053 -
Docs
5:43 PM
Rewrite AUDIT.md with final states, credential evidence, the CSP path and the advisory table
Details
Every finding now ends in Fixed, Partially Fixed, Deferred or Not Actionable. The summary counts are generated from the finding tables by tests/test_audit_counts.php, which runs with the hermetic suite so they cannot drift. Adds the Post-Audit Hardening section.
cac9227 -
Maintenance
5:27 PM
Track tools/.htaccess and tools/run-phpstan.sh
Details
/tools/* is ignored apart from a whitelist, so the deny file protecting the operator scripts and the PHPStan runner had not been committed; found by running the CI commands from a fresh clone.
307983d -
Maintenance
5:26 PM
Separate tests into hermetic, integration and live, and harden CI
Details
- tests/run-php.sh [hermetic|integration|live|all]: assertions forced on, APCu on; a test that cannot run says why and exits 2, which fails the run; sections skipped inside a passing test are counted and shown
- test_player_history exited 0 when no database was available and test_tool_auth exited 0 with the example CRON_KEY: both silent passes, now exit 2 with a reason
- tests/_support.php: requireDatabase / requireLiveApi / requireAssertions; tests/setup-integration.sh writes a config.php for integration runs
- ci.yml: frontend (lint, tests, builds), php (syntax, hermetic tests, pinned PHPStan) and integration (PostgreSQL service, real site) jobs; no secrets, no external APIs, concurrency and timeouts set
- audit.yml (npm advisories) and live.yml (Facepunch API) are scheduled/manual so third parties cannot fail a pull request
d9d67e4 -
Maintenance
5:23 PM
Run PHPStan at level 1 with no baseline, and fix what it found
Details
phpstan.neon carried ~90 ignore patterns that hid every class of error; it now runs level 1 (unknown functions, classes, methods, constants; possibly-undefined variables) over backend, auth and mcp with seven narrow, commented ignores. tools/run-phpstan.sh (npm run analyse:php) uses the version pinned in composer.lock.
Real bugs found:
- obscureIpAddress() did not exist, so the personal-data export fataled for anyone with session history
- cache-management-api called CacheManager::getInstance(), which does not exist (the class is static), so invalidating by tag or pattern fataled; pattern LIKE wildcards in the input are now escaped
- search-api sent Cache-Control: public for the signed-in user's search history and the admin analytics
- two CompressionMiddleware classes (pages and API) shared a name; the API one is ApiCompressionMiddleware
- backend/controllers/ duplicated BaseController and PackageController and nothing loaded it; backend/services/PackageService.php called functions that do not exist and had no callers
- an invalid MCP tool example repeated the 'action' key
6533174 -
Refactor
5:18 PM
Ensure claimed_orgs.is_public from deployed code, not per request
Details
The deploy has no migration step and the base schema is created by initializeDatabase() in config/config.php, which is never deployed, so existing installs can only be upgraded from code that is. ensureClaimedOrgsSchema() runs once per process and only when the catalogue lacks the column, replacing the unconditional ALTER; it is also called by getUserClaimedOrgs(), which selects the column and silently returned nothing on a fresh install until the claims API had been hit. config.example.php creates the column for new installs. tests/test_org_claims_schema.php covers existing and fresh installs.
2197b97 -
Maintenance
5:17 PM
Remove five frontend scripts nothing loads, and guard against new ones
Details
cache-management.js, dependency-graph.js, notification-bell.js, homepage-categories.js (an ES module the non-bundling build could never have run) and its only importer homepage-utils.js. Checked against templates, the core script list, imports and dynamic loads, the service worker, build config and tests. tests/test_js_referenced.php fails if a script in frontend/js is not referenced by another tracked file.
fbe3f30 -
Maintenance
5:14 PM
Take the in-range fixes for all 15 npm advisories
Details
npm update within the existing semver ranges (package.json unchanged): postcss, esbuild, vitest/vite, browserslist, nanoid, js-yaml, svgo, undici, fast-uri, brace-expansion, colord and their transitive dependencies. npm audit now reports 0 with and without dev dependencies; the CSS bundle is byte-identical and lint, tests and builds pass. npm 10.9.4's resolver crashes on this tree, so the update was run with npm 11 via npx; the lockfile format is unchanged and npm ci accepts it.
c391e49 -
Docs
5:03 PM
List the live-API tests
3c96eab -
Docs
5:02 PM
Add AUDIT.md
c5fbe62 -
Maintenance
5:01 PM
Add a hermetic PHP test runner and CI, drop unused npm packages
Details
- tests/run-php.sh (npm run test:php) runs the 32 standalone tests that need no config, database or network, with assertions forced on: test_global_stats_grid relies on assert() and passed vacuously under the default zend.assertions=-1
- .github/workflows/ci.yml runs ESLint, Stylelint, Vitest, the CSS build, a PHP syntax check and the PHP runner
- remove tabbable and fast-check, which nothing imports
e30bdc1 -
Style
12:58 PM
Use single-quoted escape map keys
42bedf2
Generated from the project's commit history whenever the site is deployed. Times are server time.