fix(apphost): register OpenRegister's autoloader before touching AppHost - #289
fix(apphost): register OpenRegister's autoloader before touching AppHost#289rubenvdlinde wants to merge 1 commit into
Conversation
ADR-040's load-order hazard, caught by gate-64 once the gate package was
actually reaching this repo.
OC_App::getEnabledApps() sort()s the app list, and Coordinator::registerApps()
walks THAT sorted list calling OC_App::registerAutoloading($appId, $path) and
then $app->register() for ONE APP AT A TIME. So every app's register() runs
BEFORE the PSR-4 prefix of every alphabetically-later app exists — on a
completely healthy instance, with OpenRegister enabled.
The fix is to put OpenRegister's prefix on the autoloader ourselves, which is
exactly what Nextcloud does a few iterations later. Two properties make this
the right call: registerAutoloading() touches ONLY the autoloader and is
idempotent (it early-returns on an $alreadyRegistered key), and it does NOT
boot the app. IAppManager::loadApp('openregister') would be wrong here — it
sets loadedApps['openregister']=true and calls Coordinator::bootApp(), booting
OpenRegister BEFORE its own register() has run.
Verified both directions with the gate itself, against this tree:
without the prelude rc=1 FAIL — AppHost adoption with no prelude
with the prelude rc=0 PASS
and under BOTH matcher versions (the one on .github main and the named-constant
fix in .github#185), so this is not a repo change chasing a gate change.
Quality Report — ConductionNL/scholiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-specs | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 750/750 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-06 08:06 UTC
Download the full PDF report from the workflow artifacts.
|
Superseded by #288, which landed as f757880. Both PRs fix the same ADR-040 load-order defect. #288 is the one that follows doriath's reference implementation: the prelude lives in its own That difference is visible in CI, not just in style: this PR is red on Closing without merging — no code is lost, #288 contains the same fix. |
What gate-64 found
lib/AppInfo/Application.phpcallsBootstrap::register(...)unguarded, with no autoload prelude.OC_App::getEnabledApps()sort()s the app list, andCoordinator::registerApps()walks that sorted list callingregisterAutoloading($appId, $path)then$app->register()one app at a time. So every app'sregister()runs before the PSR-4 prefix of every alphabetically-later app exists.For scholiq the ordering happens to be favourable today (
scholiqsorts afteropenregister), so this is latent rather than live. It stops being latent the moment OpenRegister is disabled or absent — an unguardedBootstrap::register()then throws\Error,Coordinatorcatches it, logs anemergencyandcontinues, and the app stays enabled whileServiceOverrideRegistrarandEventListenerWiringbelow it never run. Nothing in the UI says half the wiring is missing.Relying on your app id's alphabetical position relative to another app's is not a safety property. The prelude is idempotent and cheap.
Verified both directions, against this tree
rc=1FAIL — AppHost adoption with no preluderc=0PASSChecked under both matcher versions — the one on
.githubmainand the named-constant fix in.github#185— so this is not a repo change chasing a gate change.php -lclean.🤖 Generated with Claude Code