Release: merge development into beta - #1318
Conversation
The 2.0.8-beta.20260831102341 release bumped the version on beta. Without this, development stays behind beta and the next development -> beta promotion conflicts on the version file. Version files resolve to development's side, which is the higher line, so this never moves a version backwards.
Dependabot cannot propose composer updates for this app. Its updater fails
with:
Your requirements could not be resolved to an installable set of packages.
- edgedesign/phpqa[v1.27.0, ..., v1.27.2] require ext-xsl * ->
it is missing from your system.
config.platform pins php 8.3 so composer resolves against a known PHP version,
but says nothing about extensions. edgedesign/phpqa requires ext-xsl and the
resolving environment does not have it, so the resolve fails before any bump
can be computed.
CI is unaffected, which is why this went unnoticed: composer install replays
the committed lock and never re-resolves, so the pipeline stays green while
dependabot -- which does re-resolve -- fails every time. The shared quality.yml
installs no xsl extension anywhere and never invokes phpqa.
Declaring ext-xsl beside the php pin makes resolution assume exactly what the
committed lockfile already assumes. Verified in a clean composer:2 container
without --ignore-platform-reqs: the same file fails without this line and
resolves (103 installs, lock written) with it.
Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
The 2.0.8-beta.20260831105849 release bumped the version on beta. Without this, development stays behind beta and the next development -> beta promotion conflicts on the version file. Version files resolve to development's side, which is the higher line, so this never moves a version backwards.
The 2.0.8 release bumped the version on main. Without this, development stays behind main and the next development -> main promotion conflicts on the version file. Version files resolve to development's side, which is the higher line, so this never moves a version backwards.
….0.8 chore(release): sync main back into development
….0.8-beta.20260831105849 chore(release): sync beta back into development
….0.8-beta.20260831102341 chore(release): sync beta back into development
Levels this app with the fleet. 2.27.2 adds two fixes the earlier 2.27.0 pin does
not carry:
* headerless is no longer chromeless — a flat KPI card in a borderless wrapper
had no card, border or background at all;
* a stat `variant` paints from the `-text` tokens rather than the fill tokens,
which failed WCAG AA at 1.08:1 as a foreground colour. The KPI colour
cleanup converted hardcoded values to `variant`, so this is what makes those
conversions contrast-safe.
Lockfile only, and npm pruned nothing.
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ⏭️ | ||||
| phpcs | ⏭️ | ||||
| phpmd | ⏭️ | ||||
| psalm | ⏭️ | ||||
| phpstan | ⏭️ | ||||
| phpmetrics | ⏭️ | ||||
| eslint | ⏭️ | ||||
| stylelint | ⏭️ | ||||
| build | ⏭️ | ||||
| composer | ⏭️ | ⏭️ | |||
| npm | ⏭️ | ⏭️ | |||
| app:check-code | ⏭️ | ||||
| info.xml | ⏭️ | ||||
| REUSE | ⏭️ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-31 11:25 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 12:36 UTC
Download the full PDF report from the workflow artifacts.
…0260831125044 chore(sync): carry beta back into development
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 13:10 UTC
Download the full PDF report from the workflow artifacts.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 14:37 UTC
Download the full PDF report from the workflow artifacts.
Dependabot cannot update these packages. Its npm updater fails with: npm error code EOVERRIDE npm error Override for <pkg> conflicts with direct dependency The package is listed BOTH as a direct dependency and as a literal overrides entry pinned to the same range. Dependabot bumps the direct dependency and does not move the override, npm rejects the mismatched pair, and the update is abandoned -- so these packages can never be updated, security advisories included. npm's self-reference is the idiom for exactly this: $<name> tells the override to follow whatever the direct dependency resolves to, instead of a range that has to be kept in lockstep by hand. This repo already uses it (see the vue entry under @vue/test-utils). Transitive consumers still get pinned to one version -- the direct dependency's -- which is what the override was there to do. What changes is that the pin tracks the dependency instead of duplicating it. Verified in a clean container: bumping the direct dependency with the literal override reproduces the EOVERRIDE above; with the self-reference the same bump resolves. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 16:30 UTC
Download the full PDF report from the workflow artifacts.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 20:41 UTC
Download the full PDF report from the workflow artifacts.
…0260901034733 chore(sync): carry beta back into development
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 04:01 UTC
Download the full PDF report from the workflow artifacts.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 21:58 UTC
Download the full PDF report from the workflow artifacts.
…match absent (#1365) WOO-517 is the only failing test in the suite and it flaps: red on c402608, green on a07067a, red again on 6012ff5, always alone and always with 111 others passing. The extraction request reported no error in any of them. Extraction is queued work. extractFile() force-triggers it and returns as soon as the request is accepted, so the marker becomes searchable some time later. Ten seconds was enough on an idle runner and not on a loaded one, which turns a timing race into the message 'the body-text match surfaces the owning document when _content=true' — an assertion about the FEATURE, blamed for a wait that had not finished. The poll returns the moment a title appears, so a 30s ceiling costs nothing when extraction is prompt. The test budget goes to 120s to cover it, since 60s now has to hold a wait that can legitimately take half of it. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 22:37 UTC
Download the full PDF report from the workflow artifacts.
…one (#1369) * fix(e2e): give text extraction a realistic poll before declaring the match absent WOO-517 is the only failing test in the suite and it flaps: red on c402608, green on a07067a, red again on 6012ff5, always alone and always with 111 others passing. The extraction request reported no error in any of them. Extraction is queued work. extractFile() force-triggers it and returns as soon as the request is accepted, so the marker becomes searchable some time later. Ten seconds was enough on an idle runner and not on a loaded one, which turns a timing race into the message 'the body-text match surfaces the owning document when _content=true' — an assertion about the FEATURE, blamed for a wait that had not finished. The poll returns the moment a title appears, so a 30s ceiling costs nothing when extraction is prompt. The test budget goes to 120s to cover it, since 60s now has to hold a wait that can legitimately take half of it. * fix(search): resolve a document that names its publication by slug alone Content search has surfaced no body-text match since c402608. WOO-517 has failed on every run since, and it is the only failing test in the suite. assemblePublicSearchResults() drops a document row unless resolveDocumentPublicationSummary() returns a publicly-visible publication. That resolver had three paths and none of them matched the shape the fleet actually writes: M1 reads $documentRow['publication']['id'] M2 reads $documentRow['@self']['relations']['publication'] and ['publication.slug'] fallback asks the INVERSE question, a publication whose _relations contain this document, which a document→publication write never answers A document is created with 'publication' => ['slug' => ..., 'title' => ...], as a plain property, with no id and not inside _relations. So it resolved through nothing, the row was discarded, and the caller saw an empty result set, which is indistinguishable from 'nothing matched'. M1b reads the carried publication.slug and routes it through the slug lookup that already exists for the _relations form, reusing the same slug cache. On a miss it falls through to M2 exactly as before, so a document whose slug names a non-public publication is still dropped. VERIFICATION IS CI, NOT LOCAL, AND THAT IS NOT A CHOICE. This suite cannot run in a bare checkout: OCP and openregister are both absent, so all 27 tests error before asserting. With both stubbed onto the autoloader the run is identical with and without this change (27 tests, 39 assertions, 4 errors, 11 failures), because the pre-existing slug-path tests fail there too. phpcs is clean. --------- Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 00:09 UTC
Download the full PDF report from the workflow artifacts.
…1371) NOT FOR MERGE. This isolates one variable. WOO-517 passed at f156675 (09:50) and has failed on every run since c402608 (15:58). Both sides of that boundary moved: opencatalogi took the WOO-536 search rework via the beta sync, AND openregister went from 2.0.12-unstable.20260901050305 to 2.0.14-unstable.20260901212512, because additional-apps clones it unpinned at 'development'. So the bisect on opencatalogi's own SHAs could never have been conclusive. 6fc19be5 is the openregister release commit for the version the green run actually enabled. Green here means the regression is openregister's; red means it is opencatalogi's WOO-536 rework. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 02:02 UTC
Download the full PDF report from the workflow artifacts.
…0260902034607 chore(sync): carry beta back into development
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 03:51 UTC
Download the full PDF report from the workflow artifacts.
The previous pin used the commit SHA and every job died at setup with exit 128: the additional-apps clone resolves its ref with git clone --branch, which takes a branch or a tag and not an arbitrary commit. Nothing ran, so the experiment answered nothing and development was left failing at setup. v2.0.12-unstable.20260901050305 is the tag for the version the last green run enabled. Reverting as soon as this reports. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 06:09 UTC
Download the full PDF report from the workflow artifacts.
The pin was a diagnostic and is removed as promised. WITH openregister pinned to 2.0.12-unstable.20260901050305 — the version the last green run enabled, confirmed in the run log — WOO-517 STILL FAILS: 1 failed / 111 passed, identical to the unpinned runs. So the regression is NOT openregister's. It is opencatalogi's WOO-536 search rework, somewhere in assemblePublicSearchResults() past the catalog-scope guard. Recorded on #1368. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 07:18 UTC
Download the full PDF report from the workflow artifacts.
…#1381) The metadata-only assertion in WOO-517 is satisfied by an EMPTY list. It passes identically whether the endpoint correctly withheld one document or returned nothing because the anonymous caller can see no publications whatsoever. That distinction is the whole question when the _content=true half comes back empty, and the test could not tell them apart. WOO-551 removed OR's _rbacAsPublic toggle. The replacement inherits authorization at the schema level, so anonymous visibility now depends on read rules being present on the register. Without them every publication is invisible here, a document can never resolve its owning publication, and the failure reads as 'the body-text match does not surface' — an assertion about content search, blamed for an authorization gap. The seeded publication carries a past publicationDate, which is exactly what the register's read rules scope anonymous access to, so it must be visible. This makes the test say which of the two it is. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 09:26 UTC
Download the full PDF report from the workflow artifacts.
…#1383) The first control (#1381) proved anonymous callers see PUBLICATIONS: it passed on the run that still failed WOO-517, which kills the WOO-551 RBAC hypothesis I had been carrying. It does not prove they see DOCUMENTS, and the document is what has to surface. Searching its TITLE is a metadata match, so it must succeed with no _content=true at all. If it does not, the document is invisible to this caller and the body-text assertion can never pass however content search behaves — reporting a content-search failure for a visibility one, which is the same trap the first control closed one layer up. Together the two controls bisect the remaining space: publication visible plus document visible means the drop really is in the chunk-match path, and the search narrows to FileMapper::findOwningObjectUuid() and the schema-slug gate rather than anything about authorization. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 09:50 UTC
Download the full PDF report from the workflow artifacts.
…iled (#1385) ROOT CAUSE, bisected by the two controls in #1381 and #1383 rather than guessed. The anonymous caller CAN see the publication and CANNOT see the document. Content search was never involved. Since WOO-536, /api/search derives its scope from the catalog model: resolveCatalogScope() unions the registers and schemas of every listed+published catalog. It used to come from app config, whose keys were publication_register / publication_schema / document_schema — the service's own Stap 2 comment records the replacement. The document schema was in the old scope by name and is in the new one only if a catalog lists it. createCatalog() wired every fixture catalog to schemas: [SCHEMA_PUBLICATION]. No catalog in the suite listed the document schema, so documents were out of scope, and a document out of scope is invisible to every query with or without _content=true. That is the whole failure. Two changes: - the fixture catalog now covers SCHEMA_DOCUMENT as well, because a catalog that surfaces publications but not their documents cannot answer for them; - this spec creates its own catalog instead of depending on another spec having created one, which was an ordering dependency it never declared. This is why the openregister pin experiment came back red: nothing about openregister was ever wrong. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 10:16 UTC
Download the full PDF report from the workflow artifacts.
…pe (#1387) Corrects my own #1385, which was wrong twice over: it did not fix WOO-517, and it broke catalog-crud-persistence by widening a default that test asserts round-trips exactly (2 failed / 110 passed, worse than the 1 / 111 before). The real mechanism is one line up from where I was looking. resolveCatalogScope() unions only catalogs that are listed AND published, and isCatalogPubliclyAvailable() requires 'published' to be a non-empty string parsing to a date <= now. createCatalog() set listed: true and no published field at all, so EVERY catalog this fixture makes was dropped from that union silently. Adding the document schema therefore changed nothing: the catalog carrying it was never in scope to begin with. Two changes: - the fixture default goes back to schemas: [SCHEMA_PUBLICATION], which is what catalog-crud-persistence asserts, and gains a past 'published' date so the catalogs it creates actually reach the scope union; - the content-search spec names both schemas through extra.schemas, since it is the one spec that needs documents in scope. The document probe from #1383 stays the arbiter: it fails while the document is invisible and passes when it is not, whatever the reason turns out to be. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
…dcast job (#1389) * fix: wire the three orphaned pieces the flow-engine audit found Three defined-but-never-called or never-registered pieces, each one a silent hole: - WooService::publishBatch() now evaluates the configured approval chain before publishing a WOO batch. getPublishApprovalChain() was defined and never called, so any admin-settings user could publish a legally reviewable batch with zero sign-off. The gate fails closed: no chain configured, approval store unreachable, and no completed approving sequence all refuse with a translated message naming what is missing (nl + en strings added). The evaluation only reads the recorded outcome from OpenRegister's task-sequence store; the chain itself stays an OR approval-workflow construct (ADR-022). - RetentionService::applyDefaults() had no caller, leaving RET-004 (retention defaults stamped at publication) unimplemented. The new applyDefaultsAtPublication() guards on the publication register and schema, resolves the catalog slug by register/schema membership, fills only empty retention fields, and saves nothing when nothing changed, so the follow-up update event terminates instead of looping. Both OR object event listeners call it on the unpublished-to-published transition, independent of the auto-publishing options. - BackgroundJob\Broadcast is now registered in info.xml. DIR-007 requires the 4-hourly directory broadcast and even carried the status 'Bug (Not Registered in info.xml)'; the pending delegate-to-OR-webhooks change replaces how a broadcast is delivered, not whether a schedule exists, so registration is the truthful option. A manifest test keeps the registration from regressing. Also fixed encountered pre-existing defects: the listeners caught \Exception where a PHP Error would abort the OR save pipeline (now \Throwable via an injected logger), and the SchemaMapper test stub lacked findMultipleOptimized(), which fataled 5 SettingsService tests in any bare checkout. * refactor: settle the analyzer findings on the new gate code phpcs flagged the no-chain refusal line at 183 characters; the message is now the short form naming the missing setting, in the code and in all four l10n files. PHPMD flagged applyDefaultsAtPublication() at complexity 12, so the register/schema guard and the id carry-over moved into their own helpers, and WooService slid back under the 1000-line class ceiling by deduplicating the unverifiable-chain refusal. * fix: parse info.xml as a string, since the server's entity loader breaks simplexml_load_file The Nextcloud bootstrap installs a libxml external entity loader that returns null, which makes simplexml_load_file() fail on any file once the server tree is loaded, as it is on the CI runner. Read the bytes and parse with simplexml_load_string instead. Also list QualityService as @uses on StatsControllerTest so the rollup test is no longer risky and its coverage is not discarded under beStrictAboutCoverageMetadata.
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 10:56 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 11:11 UTC
Download the full PDF report from the workflow artifacts.
…or (#1391) * fix(search): admit the document schema when content search is asked for WOO-517 has been red on development since it was written: "a body-text-only match surfaces via ?_content=true and is absent without it". ROOT CAUSE. A catalog is wired at the publication register + PUBLICATION schema, so the resolved scope is publication-only. OpenRegister applies that same scope to every chunk owner its content arm resolves, and a body-text chunk belongs to a DOCUMENT. Every document match was therefore discarded inside OpenRegister and this assembler never saw a row. Reproduced on the dev instance 2026-09-02 with a freshly seeded, publicly visible publication + document + .txt, extraction confirmed, probing OpenRegister's ContentSearchHandler: CHUNK file=596 ownerUuid='f9a02425-...' RESOLVED 'f9a02425-...' rbac=true mt=false SCOPECHECK objReg=31 objSchema=1114 scope={"registers":[31],"schemas":[1113]} match=false 1113 is publication, 1114 is document. The owner resolved perfectly and was then dropped for being the very thing the search was looking for. The endpoint answered {"results":[],"total":1}, which is also why this looked like a flaky poll rather than a scope bug: the count said something matched. This is the silent drop resolveDocumentPublicationSummary()'s own docblock warned about, one layer further out. THE FIX. When `_content=true`, widen `_schemas` to the document schemas the scope's registers carry. Scoped to that flag on purpose: without it the schemas stay publication-only, so a document still MUST NOT surface on the metadata-only path, which is the test's other arm. Transitive visibility is untouched. The document rows this admits are still gated by the existing check that drops any document whose linked publication is not publicly visible. Verified live, unauthenticated, all three arms: _content=true, public publication -> total 1, rows 1 (the document) no _content -> total 0, rows 0 _content=true, publication depublished -> total 0, rows 0 * test(search): cover the document-schema widening The coverage guard was right: the widening shipped with no test at all. Seven cases, driven through reflection because both methods are private and the public entry point needs the whole OR container standing up. The cases that matter are the ones that must NOT widen. Returning a schema already in scope would duplicate a `_schemas` entry; widening on a register that carries no document schema would reach past the catalog boundary the caller's `unset()` of client-supplied `_schemas` exists to hold. Unavailable mappers, an unreadable register and an unresolvable slug each degrade to no widening, because the widening is an enhancement to a search and never a precondition for one. --------- Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 12:13 UTC
Download the full PDF report from the workflow artifacts.
…ting umbrella re-scope (#1393) * feat(retention): RET-004 defaults resolve through OR's shared decision-table evaluator The One Engine audit flagged applyDefaults()'s category/_fallback lookup as app-local rule evaluation. The stored retention_defaults shape is unchanged (no migration); RetentionPolicyTable translates it into a FIRST-policy DMN table (quoted-literal category cells, trailing '-' catch-all) and the match runs through OCA\OpenRegister\Service\Dmn\DecisionTableEvaluator, resolved with the same guarded container pattern as ObjectService. no_rule_matched and an unavailable evaluator both degrade to 'no defaults', logged - the in-app matcher is deleted, not kept as a fallback. CI stubs are signature copies of the OR classes; the unit suite runs the real grammar when a sibling OR checkout exists. openspec change: retention-defaults-on-shared-decision-tables * docs(openspec): re-scope the dcat-oai-pmh-harvesting umbrella into five shippable slices The umbrella sat at 0/177 tasks and double-counted outbound DCAT, which had already shipped as the live dcat-ap-harvest spec (DCAT-001..010). It becomes a superseded redirect with a full scope-disposition table; the 177-task list and 51-scenario delta spec are removed (git history keeps them). Successors: - oai-pmh-endpoint: outbound OAI-PMH 2.0 per catalog, fully authored (proposal/design/tasks/delta spec) and ready to hand to an agent - harvest-feed-intake: feed registration + inbound DCAT JSON-LD; scheduling moves onto the OR flow engine (TriggerScheduleNode with explicit runAs) - the app-local cron parser/scheduler/dispatcher tasks are cut - harvest-conflict-policies: the four policies + manual review - harvest-protocol-plugins: DCAT-RDF, OAI-PMH client, CKAN, schema.org - harvest-observability: SHACL gate, per-feed dashboard, run logs Also cut: RML mapping (JSON-path only) and oai_datacite. No code carried @SPEC tags into the umbrella; the two openspec references (adr-001 row, nora-architectuur-publishing) are repointed. * test(retention): complete the strict-coverage roster for the policy-table extraction CI runs beStrictAboutCoverageMetadata with a coverage driver, so executing RetentionPolicyTable outside RetentionServiceTest's roster marked 5 tests risky and voided their recorded coverage - the ratchet then read a 27% drop that no behaviour change caused. Add the @uses entry and a dedicated RetentionPolicyTableTest covering the translation grammar directly (rule order, fallback-last, quote escaping, null output entries, unusable rows). --------- Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 12:56 UTC
Download the full PDF report from the workflow artifacts.
… inside (#1395) its own card.⚠️ THE CAUSE IS AN INSET, NOT A COMPONENT. A card widget renders `flush` and then has its padding put BACK by the card-fit rule (`padding: 8px 14px`), so the KPI sits inside the wrapper while the WRAPPER draws the border, radius and background the user reads as "the card". The library's `--clickable:hover` rule then drew a 2px border and a drop shadow on the KPI itself, 8-14px in from the edge being hovered. Measured live on dossiq, while genuinely hovered: the tile carried a 2px rgb(0,103,158) border and its own shadow, inset 9px from the wrapper's top and 15px from its left. A non-card-fit tile sits at 1px, so its border lands on the wrapper's own edge and reads as one card. That inset is the whole difference, which is why it looked app-specific and was not. nextcloud-vue#932 moves the affordance to the wrapper. No layout change: nothing moves, one card outlines. Verified in the browser with a real pointer hover: before inner 2px rgb(0,103,158) + shadow wrapper grey, no shadow after inner transparent, no shadow wrapper rgb(0,103,158) + shadow Every app with clickable stat, gauge or delta tiles had this. This bump is one of the fleet sweep that clears it. Dependency change only: package.json and the nextcloud-vue entry in package-lock.json. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/opencatalogi @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-l10n | ✅ | ||||
| check-manifest | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 129/129 | |||
| npm | ✅ | ✅ 881/881 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 19:06 UTC
Download the full PDF report from the workflow artifacts.
Automated PR to sync development changes to beta for beta release.
Merging this PR will trigger the beta release workflow.