Skip to content

fix(gate-64): a named constant is the prelude, spelled better — not a missing one - #185

Closed
rubenvdlinde wants to merge 1 commit into
mainfrom
fix/gate-64-named-constant
Closed

fix(gate-64): a named constant is the prelude, spelled better — not a missing one#185
rubenvdlinde wants to merge 1 commit into
mainfrom
fix/gate-64-named-constant

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

The finding that had nothing behind it

gate-64 recognised the ADR-040 autoload prelude only as a quoted literal inside the call parentheses:

\OC_App::registerAutoloading('openregister', $path);              // accepted
\OC_App::registerAutoloading(self::OPENREGISTER_APP_ID, $path);   // REJECTED

The second is the same call with the app id given a name, four lines below private const OPENREGISTER_APP_ID = 'openregister';. doriath writes it that way — and gate-64 reported it as an AppHost adoption with no prelude, with the prelude present, correct, and unit-tested.

Measured on doriath#163: FAIL — 2 AppHost adoption(s) with no OpenRegister autoload prelude.

A gate that fails the tidier spelling of the thing it is asking for is not reporting a defect. It teaches people to write the untidy spelling, and it spends the reader's attention on nothing.

The fix, and why it does not go blind

Resolution is deliberately shallow and literal: a name counts only when the same source blob binds it to the exact string 'openregister' — via const, define(), or a plain variable. Imports are not followed, and a name that cannot be seen bound is not accepted.

That last property is the whole design. "Accept any argument" would clear doriath and blind the gate in the same stroke, so two of the four new tests exist to fail in exactly that direction.

test direction
test_named_constant_bound_to_openregister_is_GREEN doriath's shape passes
test_variable_and_define_spellings_are_accepted the other two bindings
test_constant_bound_to_another_app_still_FAILS registerAutoloading() for a different app is not a prelude
test_unknown_constant_still_FAILS an unresolvable name is not taken on trust

Mutants — disjoint sets, both directions

mutant tests turned red
accept any argument name the 2 discriminators
resolve nothing (regression to the bug) the 2 acceptance tests

Measured against the real trees

This is what settles it — the gate must lose the false positive and keep both true positives.

repo gate-64 @ main with this fix
doriath rc=1 FAIL rc=0 PASS false positive cleared
scholiq rc=1 FAIL rc=1 FAIL real defect, still caught
openbuild rc=1 FAIL rc=1 FAIL real defect, still caught

scholiq and openbuild genuinely have no prelude, and openbuild is the acute one: its class_exists(Bootstrap::class) guard answers false on a perfectly healthy instance, because openbuild sorts before openregister and Coordinator::registerApps() registers autoloading one app at a time. So Bootstrap::register() has apparently never run there, and its generic controllers, install repair steps and deep-link listener are silently absent. Those are fixed in their own repos, not here.

⚠️ Note on my own method: my first before/after table was wrong in the safe-looking direction — I copied the "baseline" helper after patching it, so both columns ran the fixed matcher and doriath appeared to pass on main. The table above is re-measured against git show origin/main: and the md5sums were checked. A baseline captured after the edit is not a baseline.

18 gate-64 tests pass.

🤖 Generated with Claude Code

… missing one

gate-64 recognised the autoload prelude only as a QUOTED LITERAL inside the
call parentheses:

    \OC_App::registerAutoloading('openregister', $path);              accepted
    \OC_App::registerAutoloading(self::OPENREGISTER_APP_ID, $path);   REJECTED

The second is the same call with the app id given a name, four lines below
`private const OPENREGISTER_APP_ID = 'openregister';`. doriath writes it that
way, and gate-64 reported it as an AppHost adoption with NO prelude — with the
prelude present, correct, and unit-tested. Measured on doriath#163:
"FAIL — 2 AppHost adoption(s) with no OpenRegister autoload prelude".

A gate that fails the tidier spelling of the thing it is asking for is not
reporting a defect; it is teaching people to write the untidy spelling, and it
spends the reader's attention on a finding that has nothing behind it.

Resolution is deliberately SHALLOW and LITERAL. A name counts only when the
same source blob binds it to the exact string 'openregister' — via `const`,
`define()` or a plain variable. Imports are not followed, and a name that
cannot be seen bound is NOT accepted.

That last point is the whole design. "Accept any argument" would clear doriath
and simultaneously blind the gate, so two of the four new tests exist to fail
in that direction:

  test_named_constant_bound_to_openregister_is_GREEN     doriath's shape passes
  test_variable_and_define_spellings_are_accepted        the other two bindings
  test_constant_bound_to_another_app_still_FAILS         registerAutoloading()
                                                         for a DIFFERENT app is
                                                         not a prelude
  test_unknown_constant_still_FAILS                      an unresolvable name is
                                                         not taken on trust

Mutation-checked both ways, and the two mutants turn DISJOINT sets red:

  accept any argument name   -> the 2 discriminators fail
  resolve nothing (the bug)  -> the 2 acceptance tests fail

Measured against the real trees, which is what settles it:

  repo        gate-64 @main   with this fix
  doriath     FAIL (rc 1)     PASS (rc 0)    false positive cleared
  scholiq     FAIL (rc 1)     FAIL (rc 1)    real defect, still caught
  openbuild   FAIL (rc 1)     FAIL (rc 1)    real defect, still caught

scholiq and openbuild genuinely have no prelude. openbuild is the acute one:
its `class_exists(Bootstrap::class)` guard answers FALSE on a healthy instance
because `openbuild` sorts before `openregister`, so Bootstrap::register() has
apparently never run there and its generic controllers, install repair steps
and deep-link listener are silently absent. Those are fixed in their own repos,
not here.

18 gate-64 tests pass.
@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Superseded by #184, which landed while this was in review and is a superset of it.

Both fixes resolve the same false positive — gate-64 matching the app id only as a quoted literal, so doriath's registerAutoloading(self::OPENREGISTER_APP_ID, $path) read as a missing prelude. #184 additionally strips comments before matching, which closes a false GREEN this PR did not address: a commented-out registerAutoloading('openregister', …) would have counted as a prelude that no longer runs. That is the more dangerous direction and it belongs in the gate.

Re-measured against the real trees with #184 as it now stands on main:

repo gate-64
doriath rc=0 PASS — false positive cleared
scholiq rc=1 FAIL — real defect, still caught
openbuild rc=1 FAIL — real defect, still caught

Identical to this PR's outcome, so nothing is lost by closing it.

The only delta here was accepting two further bindings — define('NAME', 'openregister') and $var = 'openregister' — where #184 accepts const only. No repo in the fleet uses either spelling today, so I am not re-opening it as a follow-up; if one ever does, gate-64 will say so by name and the binding can be added then with its own paired test.

The two real defects this exposed are being fixed in their own repos: ConductionNL/scholiq#289 and ConductionNL/openbuild#139.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant