PackageTrack
Sign in Get early access

conduction/hydra-gates

Hydra's mechanical quality gates, packaged so any repo can run them against its own diff. The exit code is the failure COUNT.

v1.9.0 60K downloads/mo #1859 most downloaded on Packagist ConductionNL/.github

What this package is like to depend on

Last release 2 days ago

22 Aug 2026

Ships on a steady schedule

a new release about every 8 days

Some releases are documented

notes for 10 of 18 stable releases

Nothing withdrawn

no release was ever pulled

0 months old

18 releases · first in 2026

18 releases in the last 12 months

see the full history below

Release timeline

18 releases · Aug 2026 to Aug 2026
Release Pre-release

Releases

latest 18
  1. v1.9.0 22 Aug 2026
    Release notes

    The package no longer declares

    "autoload": { "psr-4": { "OCA\\OpenRegister\\Contract\\": "hydra-gates/contracts/" } }
    

    That prefix was LONGER than openregister's own OCA\OpenRegister\ -> lib/, PSR-4
    is longest-prefix-wins, and the package installs into every consumer's vendor/ —
    so whichever app's autoloader registered first defined OpenRegister's contract
    for the whole process. Measured on a real instance: softwarecatalog's vendored
    copy was supplying openregister's own interface (.github#514, #531).

    The contracts still ship. A consumer that needs them requires them from its own
    test bootstrap behind interface_exists(), which is order-independent. See
    hydra-gates/README.md, 'The shipped OpenRegister contracts are opt-in'.

    MINOR, not MAJOR, deliberately: every app constrains this package with a ^1
    caret, so a 2.0.0 would reach nobody and the fleet would keep the defect. The
    four consumers that relied on the implicit autoload — buildiq, decidiq, filinq,
    stackiq — are migrated and verified on development ahead of this tag. The other
    apps either ship their own contract stubs (dossiq, pipelinq, shillinq), own the
    real one (openregister), or never reference it.

    Open source →
  2. v1.8.2 20 Aug 2026
    Release notes

    quality-config/phpstan-base.neon gains two settings so the fleet's nine
    phpstan/phpstan 1.12.33 -> 2.x dependabot PRs stop failing on migration
    behaviour rather than on defects:

    treatPhpDocTypesAsCertain: false 2.x narrows types declared only in a
    docblock and reports the defensive
    checks against them as already-decided.
    ignoreErrors phpDoc.parseError @SuppressWarnings is PHPMD's tag; 2.x
    parses it as its own and fails on
    PHPMD's rule syntax.

    Measured on decidesk with 2.2.8: 60 -> 22 errors. The residual 22 are real
    per-app debt and are NOT masked.

    Verified on BOTH majors, since 17 of 18 apps still run 1.12.33:
    2.2.8 60 -> 22 errors
    1.12.33 exit 0, '[OK] No errors', no configuration error, and still
    'Found 1 error' on a deliberately broken file — so it is
    analysing, not silently skipping.

    Open source →
  3. v1.8.1 20 Aug 2026
    Release notes

    Cut because v1.8.0 shipped an ObjectServiceInterface WITHOUT patchObject()
    and with updateObject() still summarised as "Apply a partial update to an
    existing object" — the exact wording that sent a consumer down the erasing
    path. The correction landed on main in f8cad2f two days after v1.8.0 was
    tagged, and every app has been pinned to the broken copy ever since.

    That is not confined to documentation. hydra-gates claims the app's own
    namespace in its composer autoload:

    "psr-4": { "OCA\\OpenRegister\\Contract\\": "hydra-gates/contracts/" }
    

    which is a LONGER prefix than openregister's own OCA\OpenRegister\ -> lib/,
    so the gate package wins. Nine repos vendor it, so under OC_App::loadApps()
    whichever app registers first defines the contract for the whole instance.
    Measured on a running instance: softwarecatalog's vendor directory was
    supplying openregister's interface, and patchObject() — the read-merge-write
    path — was unreachable through the type consumers bind to.

    openregister/tests/Unit/Service/ObjectServiceUpdateVersusPatchTest catches
    all three symptoms; it has been failing on that, and only that, out of
    16 839 tests.

    Also carries everything else merged on main since v1.8.0, including gate
    behaviour changes (phpcs errors fail the gate #483, gate-8 judges how the
    caller consumes the null #506, coverage-guard ignores deletions #480) and
    the release step now bumping openapi.json alongside appinfo/info.xml (#515,
    which had left all six of opencatalogi's PHPUnit cells red).

    Open source →
  4. v1.8.0 15 Aug 2026
    Release notes

    v1.8.0 — publish the OpenRegister contract, and gate that it stays on…

    Open source →
  5. v1.7.3 12 Aug 2026
    Release notes

    v1.7.2 appended the (?) optional marker to two excludePaths entries. Measured
    against the real apps, that made PHPStan 2.x WORSE: NEON reads … (?) after a
    %…% expansion as an ENTITY, so 2.x died with

    FileExcluder::isAbsolutePath(): Argument #1 ($path) must be of type string,
    Nette\DI\Definitions\Statement given

    Quoting the whole value fixes 2.x but breaks 1.x, which then does NOT strip the
    marker and resolves the literal "/app/vendor-bin (?)" — a path matching nothing.
    Harmless where the directory is absent, and silently breaking where it exists:
    openbuild ships 31 files under lib/Resources/template.

    So a conditional path has no spelling that is safe on both majors, and it leaves
    the base. vendor is the only entry that always exists. The other two move to
    the apps that actually have the directory:

    vendor-bin openregister only
    lib/Resources/template portaliq, openbuild, hermiq

    Verified on zaakafhandelapp (PHPStan 2.2.8, the fleet's only 2.x app) with its
    temporary override removed: 57 files analysed, no errors. The [OK] No errors
    line was not taken as proof — a zero-file run prints the same thing, which was
    the original defect.

    Open source →
  6. v1.7.2 12 Aug 2026
    Release notes

    excludePaths named vendor-bin and lib/Resources/template without the (?)
    optional marker. PHPStan 2.x VALIDATES excludePaths and aborts when an entry
    names something that does not exist; 1.x accepts it silently, which is why this
    went unnoticed through v1.7.0 and v1.7.1.

    zaakafhandelapp is the only fleet app on PHPStan 2 (2.2.8; the other seventeen
    are on 1.12.33). It has neither directory, so including the base unchanged made
    composer phpstan exit before analysing a single file — the same failure shape
    as v1.7.0's relative paths, from a different cause.

    vendor stays mandatory: phpstan runs from vendor/bin, so it always exists.

    The marker is stripped during resolution, so no app's resolved value changes —
    verified on docudesk (PHPStan 1.12.33) with a planted no-such-dir-control (?),
    which analysed cleanly and dumped as a plain path.

    Open source →
  7. v1.7.1 12 Aug 2026
    Release notes

    The base shipped in v1.7.0 declaring paths, bootstrapFiles, excludePaths and
    scanDirectories as bare relative paths. PHPStan resolves those against the
    config file that DECLARES them, so consumed from
    vendor/conduction/hydra-gates/quality-config/ they pointed at
    vendor/.../quality-config/lib — which does not exist. The run aborts with
    'Path ... does not exist', or worse analyses nothing.

    It was invisible for the same reason every dead gate in this fleet's history has
    been: no app had adopted it yet, so nothing was red. The defect shipped inside a
    release whose whole purpose was to centralise configuration.

    This is also the SECOND time today the same mechanic has bitten. quality-config/
    phpcs.xml carries a load-bearing comment explaining that phpcs resolves
    relative to the declaring ruleset and that the app stub must therefore own it —
    and phpstan-base.neon was written straight afterwards with the identical mistake
    in a different tool's syntax. Knowing the general rule did not transfer.

    Fixed with %currentWorkingDirectory% prefixes. Verified on larpingapp with
    phpstan dump-parameters: level, paths, excludePaths, bootstrapFiles and
    scanDirectories all resolve to byte-identical values against a local config,
    findings unchanged.

    Open source →
  8. v1.7.0 12 Aug 2026
    Release notes

    v1.7.0 — gate-65 coding-standard-adoption, quality-config, Nextcloud-…

    Open source →
  9. v1.6.0 07 Aug 2026
    Release notes

    fix(gates): make the opt-outs reachable, stop rejecting \Throwable, e…

    Open source →
  10. v1.5.2 06 Aug 2026
    Release notes

    v1.5.1 counted gate-28 as APPLICABLE whenever lib/ existed and
    composer.json declared a license, regardless of whether the PR touched a
    single PHP file. A PR that changes only a workflow, a lockfile, a spec or an
    info.xml therefore fails on:

    [gate-28] license-triangle: SKIPPED (structural) — ... 0 in-scope
    lib/**/*.php file carried an @license ... so NOTHING was compared

    with hydra-gates-require-full-coverage on, which is now the default. The
    gate was right that it compared nothing; it was wrong about why. Nothing was
    in scope, which is ADR-020's diff-scoping doing its job, and that is exactly
    what the NOT-APPLICABLE classification exists to say.

    Tagged because the fix has been sitting on main untagged, and every consumer
    pins a tag — an untagged fix reaches nobody. Observed on openregister#2365,
    whose diff is info.xml + package.json + a lockfile + one spec.

    Open source →
  11. v1.5.1 06 Aug 2026

    Nothing published for this version

  12. v1.5.0 06 Aug 2026

    Nothing published for this version

  13. v1.4.0 05 Aug 2026

    Nothing published for this version

  14. v1.3.0 05 Aug 2026

    Nothing published for this version

  15. v1.2.0 05 Aug 2026

    Nothing published for this version

  16. v1.1.0 04 Aug 2026

    Nothing published for this version

  17. v1.0.1 03 Aug 2026

    Nothing published for this version

  18. v1.0.0 03 Aug 2026

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive