Summary
Gate 5 (route-auth) resolves a route name to lib/Controller/<Name>Controller.php by Nextcloud's default naming convention. That mapping is wrong for any app that adopts ADR-040 AppHost, where the generic controllers are aliased onto the app's conventional controller class names at runtime by \OCA\OpenRegister\AppHost\Bootstrap::register(). The file the gate looks for does not exist in the consuming app by design.
The gate reports this as missing, which reads as "this routed method has no auth attribute" — a security finding — when the truth is "the gate could not resolve the controller".
Reproduction
ConductionNL/scholiq @ development (7f7feea), gate package v1.0.1:
[gate-5] route-auth: FAIL — 4 routed method(s) missing auth attribute
health#index — lib/Controller/HealthController.php missing
metrics#index — lib/Controller/MetricsController.php missing
preferences#getPreference — lib/Controller/PreferencesController.php missing
preferences#setPreference — lib/Controller/PreferencesController.php missing
scholiq/lib/Controller/ contains no HealthController.php, MetricsController.php or PreferencesController.php, and grep -rl HealthController lib/ returns nothing. appinfo/routes.php says so explicitly:
AppHost adoption (ADR-040): the settings, preferences, health and metrics controllers are the OpenRegister AppHost generics, aliased onto Scholiq's conventional controller class names in lib/AppInfo/Application.php via \OCA\OpenRegister\AppHost\Bootstrap::register().
lib/AppInfo/Application.php:73 imports OCA\OpenRegister\AppHost\Bootstrap and calls Bootstrap::register(...) at line 136.
The auth attributes for those methods live on the generic controllers inside the openregister package. The gate never looks there, so it cannot see them either way — it is not that the attributes are absent, it is that the gate is looking in the wrong repository.
Second, separable defect: gate 5 is not diff-scoped
The run above was scoped to a diff of package.json + package-lock.json — a @conduction/nextcloud-vue dependency bump, zero PHP touched. Gate 5 still fired with 4 findings.
ADR-020 diff-scoping is what makes this tier safe to switch on in a repo with inherited debt (gates 16, 19, 26 and 61 honour it). Gate 5 scanning appinfo/routes.php wholesale means that on scholiq every PR, including a Dependabot bump, is blocked by a finding it did not introduce and cannot fix.
Impact
This is why enable-hydra-gates has not been switched on for scholiq. Any AppHost-adopting app will hit the same wall on its first run.
Suggested direction (not applied — this is a gate defect, not app debt)
- Distinguish "controller class not resolvable in this repo" from "auth attribute absent". They are different findings and only one of them is a security signal. A
SKIP/UNRESOLVED verdict naming the unresolved class would be honest; a silent missing is not.
- Teach the resolver about
AppHost\Bootstrap::register() aliasing, or read the alias map, so aliased routes resolve to the generic controller.
- Diff-scope gate 5 per ADR-020 so inherited routes cannot block an unrelated PR.
Deliberately not doing the obvious workaround of adding stub controllers or auth attributes to scholiq to satisfy the check — that would be changing correct code to satisfy a broken gate.
Summary
Gate 5 (
route-auth) resolves a route name tolib/Controller/<Name>Controller.phpby Nextcloud's default naming convention. That mapping is wrong for any app that adopts ADR-040 AppHost, where the generic controllers are aliased onto the app's conventional controller class names at runtime by\OCA\OpenRegister\AppHost\Bootstrap::register(). The file the gate looks for does not exist in the consuming app by design.The gate reports this as
missing, which reads as "this routed method has no auth attribute" — a security finding — when the truth is "the gate could not resolve the controller".Reproduction
ConductionNL/scholiq@development(7f7feea), gate packagev1.0.1:scholiq/lib/Controller/contains noHealthController.php,MetricsController.phporPreferencesController.php, andgrep -rl HealthController lib/returns nothing.appinfo/routes.phpsays so explicitly:lib/AppInfo/Application.php:73importsOCA\OpenRegister\AppHost\Bootstrapand callsBootstrap::register(...)at line 136.The auth attributes for those methods live on the generic controllers inside the openregister package. The gate never looks there, so it cannot see them either way — it is not that the attributes are absent, it is that the gate is looking in the wrong repository.
Second, separable defect: gate 5 is not diff-scoped
The run above was scoped to a diff of
package.json+package-lock.json— a@conduction/nextcloud-vuedependency bump, zero PHP touched. Gate 5 still fired with 4 findings.ADR-020 diff-scoping is what makes this tier safe to switch on in a repo with inherited debt (gates 16, 19, 26 and 61 honour it). Gate 5 scanning
appinfo/routes.phpwholesale means that on scholiq every PR, including a Dependabot bump, is blocked by a finding it did not introduce and cannot fix.Impact
This is why
enable-hydra-gateshas not been switched on for scholiq. Any AppHost-adopting app will hit the same wall on its first run.Suggested direction (not applied — this is a gate defect, not app debt)
SKIP/UNRESOLVEDverdict naming the unresolved class would be honest; a silentmissingis not.AppHost\Bootstrap::register()aliasing, or read the alias map, so aliased routes resolve to the generic controller.Deliberately not doing the obvious workaround of adding stub controllers or auth attributes to scholiq to satisfy the check — that would be changing correct code to satisfy a broken gate.