Skip to content

gate-14: AppHost detection greps only Application.php, so a decomposed registrar re-opens the FP #199 closed #237

Description

@rubenvdlinde

.github#199 ("an AppHost generic the leaf registers itself is not an unreachable route") is merged, and gate-14 still reports 4 false controller-class-not-found findings on procest at hydra-gates@main (756fe89, i.e. after #199).

Measured

$ hydra-gates --app-dir <procest@084fbf03> --full
[gate-14] route-reachability: FAIL — 4 unrouted method(s) or wrong-target route(s)

lib/Controller/HealthController.php      route='health#index'                rule=controller-class-not-found
lib/Controller/MetricsController.php     route='metrics#index'               rule=controller-class-not-found
lib/Controller/PreferencesController.php route='preferences#getPreference'   rule=controller-class-not-found
lib/Controller/PreferencesController.php route='preferences#setPreference'   rule=controller-class-not-found

All four are served. OCA\\OpenRegister\\AppHost\\Bootstrap::registerControllers() binds OCA\\Procest\\Controller\\HealthController etc. to its generics via aliasControllerUnlessLeafDefinesIt(). The absence of the files is deliberate and required — creating them would make the alias skip and break the routes.

Cause

run-hydra-gates.sh L483-488:

_HYDRA_APPHOST=0
if [ -f lib/AppInfo/Application.php ] \
    && grep -qE 'AppHost\\+Bootstrap' lib/AppInfo/Application.php \
    && grep -qE 'Bootstrap::register[[:space:]]*\(' lib/AppInfo/Application.php; then
    _HYDRA_APPHOST=1
fi

Both probes are pinned to lib/AppInfo/Application.php. procest does not call Bootstrap::register() there; it delegates Application.phpRegistrar/ServiceRegistrar.phpRegistrar/AppHostRegistrar.php:121. So _HYDRA_APPHOST=0, _apphost_serves() returns 1 for every slug, and the legitimate-absence branch is unreachable. _di_binds_controller() cannot rescue it either — it is also scoped to Application.php (L534).

Measured, with a positive control so a zero is not mistaken for a broken grep:

$ grep -cE 'AppHost\\+Bootstrap'                lib/AppInfo/Application.php   -> 0
$ grep -cE 'Bootstrap::register[[:space:]]*\('   lib/AppInfo/Application.php   -> 0
# same two greps against a file that DOES contain the patterns:
$ grep -cE 'AppHost\\+Bootstrap'                /tmp/probe.php                -> 1
$ grep -cE 'Bootstrap::register[[:space:]]*\('   /tmp/probe.php                -> 1
$ grep -rn 'Bootstrap::register' lib/AppInfo/
  lib/AppInfo/Registrar/AppHostRegistrar.php:121:        Bootstrap::register(

Why this matters beyond one repo

The trigger was a quality change. procest#717 ("decompose Application bootstrap", a phpmd remediation) moved the call out of Application.php into a registrar. Decomposing a god-object composition root is exactly what the other gates push apps toward — and doing it silently turns gate-14 red on correct code. Any app that has done, or will do, the same refactor is affected.

Suggested fix

Widen both probes from lib/AppInfo/Application.php to lib/AppInfo/ (recursive), keeping the evidence requirement unchanged — still the literal Bootstrap::register( / the exact fully-qualified class name, never a wildcard, so a genuinely missing controller still fails.

Worth a fixture for the decomposed-registrar shape: the current test suite presumably only covers the inline-in-Application.php shape, which is why #199 read as complete.

Not a duplicate of

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions