Skip to content

Release: merge development into beta - #300

Open
github-actions[bot] wants to merge 90 commits into
betafrom
development
Open

Release: merge development into beta#300
github-actions[bot] wants to merge 90 commits into
betafrom
development

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR to sync development changes to beta for beta release.

Merging this PR will trigger the beta release workflow.

Reminder: Add a major, minor, or patch label to this PR to control the version bump. Default is patch.

juanclaude-conduction and others added 8 commits August 20, 2026 22:28
…sedes #259)

Bumps conduction/hydra-gates to ^1.8.2 alongside phpstan ^2.0; the lockfile
pinned v1.8.1 so the fleet migration config from ConductionNL/.github#517 was
not in effect here.

Seven residual errors, all genuine:

  4  catch.neverThrown       'catch (DoesNotExistException|MultipleObjectsReturnedException)'
                             around EncryptionSuiteMapper::findActiveByOwner().

                             I checked this one twice, because removing a catch
                             is how you turn a handled case into a 500. The
                             first read was that QBMapper::findEntity() DOES
                             declare @throws MultipleObjectsReturnedException,
                             so the catch looked live and the mapper's docblock
                             merely incomplete. Reading the mapper BODY settled
                             it: findActiveByOwner() ends with setMaxResults(1),
                             so findEntity() can never see two rows. That bound
                             is itself the fix for the bug the mapper's own
                             docblock describes — the unbounded version threw
                             mid-migration and this very catch then reported
                             'No active encryption suite' to a user who had two.
                             The arm is unreachable by construction. Removed
                             from the 4 sites phpstan flags; the OTHER four
                             identical-looking catches in SecretService are left
                             alone, because they wrap calls that are not bounded.

  2  notIdentical.alwaysTrue '!== ""' after isset() on the LAST regex group —
                             PHP omits a trailing unmatched group rather than
                             setting it to '', so isset() already covers '{16}'
                             — and 'hasPassword: ($salt !== "")' where the guard
                             above throws on an empty salt.

  1  property.unusedType     BreachProxyController::$cache declared ?ICache and
                             never assigned null: ICacheFactory::createDistributed()
                             returns a no-op ICache, not null. Made it non-nullable
                             and dropped the two now-pointless ?-> calls.

Verified: phpstan 2.2.8 exit 0, phpcs exit 0, php -l clean.

PHPUnit: 1031 tests, 1 error (EncryptServiceTest RSA-under-certificate). PRE-
EXISTING — reproduces identically with these changes stashed.
gate-16 spec-coverage failed this PR with "1 changed method(s) missing
@SPEC". The method is `extractLength()`, whose quantifier handling this PR
touched; it carried no `@spec` tag, and neither does anything else in the
file.

Anchored to `openspec/specs/key-generator/spec.md#requirement-regex-override`
— the requirement that defines the `{n}` / `{n,m}` length quantifier this
method parses.

While confirming the anchor I re-checked the claim the changed code rests
on, because getting it wrong would silently set `$max` to 0:

  php > preg_match('/\{(\d+)(?:,(\d+))?\}/', '{16}',   $m);  // ["{16}","16"]        isset($m[2]) === false
  php > preg_match('/\{(\d+)(?:,(\d+))?\}/', '{8,16}', $m);  // ["{8,16}","8","16"]  isset($m[2]) === true

PHP omits a trailing unmatched group entirely rather than setting it to
'', so `isset()` alone is sufficient and the `!== ''` conjunct really was
unreachable. Had group 2 been a MIDDLE group it would have been '' and
`(int)''` would have made `$max` 0 — which is why this one was worth
proving rather than assuming.

Locally the gate now reports 6 remaining, all in `src/**` Vue/JS files that
are not in this PR's diff; they come from the shallow local base ref, not
from this branch. CI, which diffs against the real merge-base, reported
exactly the one fixed here.
build(deps-dev): take phpstan 2 and clear the debt it surfaces (supersedes #259)
…60821001126

chore(release): 0.1.6-unstable.20260821001126
…60821003327

chore(release): 0.1.6-unstable.20260821003327
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ 8ebd3bb

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 00:52 UTC

Download the full PDF report from the workflow artifacts.

…60821005034

chore(release): 0.1.6-unstable.20260821005034
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ e1f9be7

Check PHP Vue Security License Tests
lint
phpcs ⏭️
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint ⏭️
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 01:03 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ 55772a6

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 01:17 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ b1fd636

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 01:38 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ 5cc16b4

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 02:02 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ b560227

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 02:17 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/doriath @ cf53ff0

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
composer ✅ 117/117
npm ✅ 533/533
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-21 02:35 UTC

Download the full PDF report from the workflow artifacts.

…60821023224

chore(release): 0.1.6-unstable.20260821023224
rubenvdlinde and others added 2 commits August 24, 2026 09:17
hydra-gates v1.9.0 -> v1.9.0
nc-vue      2.11.1 -> 2.15.0

Lock-only: both packages are already declared with caret ranges that
permit these versions, so nothing about what this app ACCEPTS changes
- only what it currently resolves to. Opened by the weekly fleet
shared-dependency bump, because a lock nobody re-resolves is a pin
nobody chose.

Merging is gated by this repository's own suite, deliberately: taking
hydra-gates v1.8.1 added patchObject() to a published interface, which
is a load-time fatal for any concrete double that implements it without
the method. CI is the only thing that can tell a safe bump from that.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ cfb9db3

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 08:20 UTC

Download the full PDF report from the workflow artifacts.

…pplication id (#426)

OpenRegister resolves a REGISTER by slug alone, but a SCHEMA by the PAIR
(application, slug) via SchemaMapper::findByApplicationAndSlug(). This app passes
appId: Application::APP_ID = 'keepiq', while every schema it already owns still
carries application = 'doriath'. The pair matches nothing, and ImportHandler's
not-found branch is not an error path — it is the create-a-new-one path. The next
import therefore builds a second, EMPTY schema set under the new application id
while every stored object stays bound to the old rows. Nothing errors; the app
renders empty collections.

Registered ahead of InitializeSettings in both blocks, because that step is what
triggers the import via SettingsService.

doriath did not appear in the live fleet measurement, so on that instance the step
reports 'nothing to do' and writes nothing; the gap it closes is measured elsewhere
in the fleet (231 under docudesk, 200 under openconnector, 180 under procest).

The step refuses rather than merges where a slug already has a twin under the new
application id, distinguishes a FAILED READ from an EMPTY RESULT, never deletes a
schema and never throws — it runs under <install>, where an escaping exception
aborts the install.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 3993772

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 10:49 UTC

Download the full PDF report from the workflow artifacts.

…anch (#428)

* fix(docs): publish the documentation from development, not a stale branch

This workflow triggered on `push: branches: [documentation]`. That branch
exists, which is why nothing ever looked broken — but nobody updates it. Its
last commit predates most of this year's work: larpinq 19 May (development is
594 commits ahead), buildiq 9 July (980 ahead).

So the docs pipeline has been faithfully republishing a months-old snapshot, and
reporting success every time. It is the reason larpinq.conduction.nl still says
"LarpingApp" and decidiq.conduction.nl still says "Decidesk" while both repos'
docs sources have said the new name since the app-id rename merged. The rename
was never missed in the docs — the docs were publishing from somewhere else.

Four of the twelve fleet apps (dossiq, integriq, stackiq, thematiq) already point
at `development`. This brings the rest in line.

Pairs with ConductionNL/.github#555, which made the reusable workflow publish to
the Cloudflare Worker that actually serves the host — previously it wrote
gh-pages and nothing read it. Both halves are needed: one fixes WHERE the docs go,
this one fixes WHICH COMMIT they come from.

* fix(docs): name the worker that actually serves this site

The trigger fix in this PR makes the docs workflow run. This commit makes
the run reach the edge.

`worker-name` was never passed, so the callee derived it from `cname`.
Since the app-id rename `cname` is the NEW host, and the worker that
actually holds the custom domains is still named after the OLD app id.
The derived name therefore points at a worker that does not exist —
deploying it CREATES a second worker while both custom domains keep
routing to the original. Every deploy green, reaching nobody, with the
live-site verification added in ConductionNL/.github#555 as the only
thing that would ever have noticed.

Pinning the name also decouples the worker from `cname`, so the docs host
can move to the new subdomain later without silently forking the worker.

Measured today: the live host still serves the pre-rename title, which is
the staleness this PR chain exists to end.

* fix(docs): stop MDX parsing a placeholder as a JSX tag

The docs build FAILS, and has been failing — it was simply never run,
because the workflow triggered on a branch nobody updates. Making the
trigger correct surfaced it on the first run.

  Error: MDX compilation failed for application-secret-requests.md
  Cause: Expected a closing tag for `<date>` (27:39-27:45)

`<date>` was written as a plain-English placeholder inside a table cell.
MDX reads it as an opening JSX tag, finds no closing tag, and aborts the
whole client bundle — so no page of this site could publish, whatever the
workflow did.

Backticks the two placeholders. They now render as code, which is what a
placeholder should look like anyway, and the sentence is unchanged.

Verified locally: npm ci --legacy-peer-deps && npm run build now exits 0
with all 10 AI-baseline checks passing.
GitHub (ConductionNL) is the only host for this org. Codeberg was a mirror
and is not used — including for issues — so this codeberg.org URL was dead.

The link also carried a pre-rename repo name: the repo is `keepiq` on
GitHub, not `doriath`. Note that github.com/ConductionNL/doriath still
returns 200 because GitHub redirects a rename — a working URL is not proof
of the current repo name, so the canonical `keepiq` slug is used here.

Only the `repo` URL changed. The sibling `"app": "doriath"` field is the
Nextcloud app id, a runtime-resolved identifier whose move is a separate
coordinated change; rewriting it here would silently break duck-typed
cross-app lookups, so it is left as-is.

Issue/PR-number policy (no instances in this repo, stated for consistency
with the fleet sweep): Codeberg issue and PR numbers do NOT correspond to
GitHub ones, so such links are de-linked to plain text rather than having
their host rewritten — rewriting would point at a real but unrelated
GitHub issue. This repo contained no issue or PR links.

Left untouched deliberately:
- `.forgejo/` workflows — `runs-on: codeberg-medium` and the
  `code.forgejo.org/actions/*` refs are Forgejo CI runner labels and action
  sources, not stale links. Flagged for a separate human decision.
- `docs/.docusaurus/` — a committed Docusaurus build cache marked
  DONT-EDIT-THIS-FOLDER. Its JSON-LD `sameAs` Codeberg org URL is emitted by
  the external `@conduction/docusaurus-preset` dependency; the fix belongs
  upstream, and editing the artifact would be overwritten on the next build.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 6e07ffe

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 16:08 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ d682eb0

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 17:07 UTC

Download the full PDF report from the workflow artifacts.

* fix(docs): pass secrets to the reusable documentation workflow

A called workflow receives no secrets from its caller unless they are passed
explicitly or inherited. Without `secrets: inherit` the callee sees an empty
`secrets.CF_API_TOKEN`, its "Publish to the Cloudflare Worker" step skips
itself on its own guard, and the run finishes green having written only
gh-pages — which nothing serves. The live docs site never changes and no
check goes red to say so.

Measured on planninq run 32715324775: all three jobs green, GitHub Pages
deploy success, Worker publish skipped, warn step reporting the Worker was
not updated.

* fix(docs): map the Cloudflare secrets explicitly instead of inheriting all

`secrets: inherit` handed the reusable documentation workflow every secret
this repo holds — the Nextcloud signing cert and key, the appstore token, the
deploy keys — for the sake of two Cloudflare values.

It also would not have worked. The org secrets are CLOUDFLARE_API_TOKEN /
CLOUDFLARE_ACCOUNT_ID and `inherit` passes secrets under their original names,
while the callee reads CF_API_TOKEN / CF_ACCOUNT_ID — so the publish step
would still have skipped itself and the run would still have gone green over
an unchanged live site.

Maps the two names explicitly instead, so nothing else crosses the boundary.
Depends on ConductionNL/.github#568, which declares both as optional secrets
on the callee: an explicit mapping only compiles for names the callee declares.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 7b22532

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 18:53 UTC

Download the full PDF report from the workflow artifacts.

github-actions Bot and others added 3 commits August 24, 2026 22:15
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
GitHub is the only host this organisation publishes to. No local checkout has
a Codeberg git remote, so nothing is pushed there and no workflow under
.forgejo/ has ever run for this repository.

This repository held no issue templates under `.forgejo/` — only workflows.

This repository had no `.forgejo` release workflow. Its release path,
`.github/workflows/cli-release.yml, release.yml`, is untouched.

.github/workflows/ is untouched — that is the live CI. Any CODEBERG_TOKEN
reference lived only inside the deleted files and goes with them.

Removes 5 file(s) under .forgejo/.
…ist (#435)

The mapping read `secrets.CLOUDFLARE_API_TOKEN` / `secrets.CLOUDFLARE_ACCOUNT_ID`,
which are not secrets anywhere in this org. Mapping from a non-existent secret is
not an error - it yields an empty string - so the callee's "Publish to the
Cloudflare Worker" step skipped itself on its own guard and the run stayed green
while the live docs site kept its pre-rename build.

The real org secrets are CF_API_TOKEN / CF_ACCOUNT_ID, the same names the callee
declares and the same ones ConductionNL/.github deploy-docs.yml reads directly.
Only the mapping values change; the keys stay.

The comment justifying the explicit mapping claimed the names differ on each
side. They do not, and that claim is what produced the bug. Replaced with the
reason that still holds: `secrets: inherit` would hand the callee every secret
this repo holds for the sake of two Cloudflare values.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ a3ff947

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-24 21:25 UTC

Download the full PDF report from the workflow artifacts.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 08a325f

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-24 22:22 UTC

Download the full PDF report from the workflow artifacts.

remko48 and others added 2 commits August 25, 2026 07:55
…rd banners (#430)

* refactor(menu): declutter the navigation into the old minimal shape

Stage 1 of the original-look restyle. The Vault menu entry becomes
\"All secrets\" with a key icon (KeyVariant registered in src/icons.js —
unregistered icon names render no icon at all), and the Certificates and
Emergency access entries move from the footer to the settings foldout.
Documentation, Features & roadmap, My activity and Password health
deliberately stay in the footer.

Also removes the duplicated \"Personal settings\" opener: CnAppNav
auto-prepends its own entry at the top of the settings foldout while the
manifest already declares the UserSettings entry (action: user-settings),
so the same dialog had two openers. nav.includePersonalSettings:false
keeps the explicit manifest entry as the only one — the e2e specs assert
it, and the upcoming manifest-driven nav override renders it directly.
The manifest schema rejects _note on nav and menu entries, hence this
explanation lives here.

Placement assertions in page-surfaces.spec.ts follow the relabel and the
two moved entries; the local restyle plan file is gitignored.

* feat(settings): show the app version in the user-settings dialog

* fix(dashboard): drop the three permanently-blank banner cards
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ e434013

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-25 06:13 UTC

Download the full PDF report from the workflow artifacts.

… and development (#440)

The event suffix applied only when ref_name was main or development, so on every
other branch push and pull_request computed the SAME group and
cancel-in-progress made them kill each other — contradicting the comment above
it, which already says push, dispatch and schedule each get their own lane.

Reachable since the push allow-list widened on 2026-08-14 to include feat/**,
fix/**, perf/**, refactor/** and chore/**: those branches now get both a push
run and a pull_request run for one commit.

quality / Quality Report is a needs:-gated aggregator that reports FAILURE when
its dependencies are cancelled, so this shows up as a red gate on a PR that was
never evaluated, and re-running collides the same way.

Already applied to openregister, integriq and pipelinq, where cancellations went
to zero. See ConductionNL/.github#563.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 485d407

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-25 10:05 UTC

Download the full PDF report from the workflow artifacts.

github-actions Bot and others added 2 commits August 25, 2026 15:29
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.8 to 2.2.9.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/keepiq @ 72393bb

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 111/111
npm ✅ 550/550
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-25 22:28 UTC

Download the full PDF report from the workflow artifacts.

github-actions Bot and others added 5 commits August 26, 2026 10:56
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Part of the 2026-08-25 fleet structure audit (ADR-100 Decision 2: the
repository root is a closed set; generated files are never tracked).

Ignore rules added: RESTYLE-PLAN.md .stale/ /.e2e-state/ .phpunit.result.cache

Untracked (kept on disk, now ignored where a rule covers them):
  - Vault-app.docx
  - npx

`.stale/` was missing from ALL 19 fleet repos and is the one that
matters most operationally: agent scratch there grew unbounded and
filled the dev disk once already.

Refs ConductionNL/hydra ADR-100.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Without target-branch, dependabot opens against the repository's DEFAULT
branch (main). Branch protection refuses any PR to main that does not come
from beta or hotfix/*, so every one of those PRs is unmergeable BY
CONSTRUCTION and simply accumulates.

Measured across the fleet: 15 repos had no target-branch at all, and their
dependabot PRs all sit against main failing branch-protection/check-branch.
The repos that already set it (humaniq, versioniq, thematiq, dossiq, shillinq,
decidiq, buildiq) open against development and merge normally.

Cooldown windows and open-pull-requests-limit are untouched.
* fix(l10n): translate the 11 untranslated manifest strings

Same defect as dossiq, portaliq and pipelinq: the manifest is data the renderer
walks, not source the l10n extractor scans, so CnAppNav's `menu[].label` and
CnPageHeader's `title` / `description` looked up keys that were never in the
catalogue. A missing key falls back to the English source and nothing reports
it, so a Dutch user reads English.

Eleven strings, all nav labels and dashboard copy: Applicaties, Certificaten,
Noodtoegang, Kluis vergrendelen, Kluisoverzicht, Rotatie verlopen, Beveiligd
bericht.

NOT TOUCHED, deliberately: this app's en.json holds 996 keys and nl.json 586,
so 410 strings have no Dutch at all. That is a real gap and it is NOT what this
change fixes. I left it rather than closing it, because the tempting fix is to
copy the English value into nl.json and that is worse than the gap: an entry
whose Dutch IS the English reads as translated to every tool that checks for
presence, so the string can never be found again. I did exactly that by
accident on pipelinq and had to unpick 43 of them. Those 410 need real
translation, as their own piece of work.

Verified: 0 manifest strings missing Dutch, check:manifest PASS.

* fix(l10n): keep the new keys out of en.json, the parity ratchet is fleet-wide

Reverting the en.json half of the previous commit. Adding the eleven strings
to en.json is the obvious move and it breaks `test:l10n`:

    A locale may never lose ground. … +568 more missing

check-l10n-parity.js is a RATCHET over EVERY required locale: the official
language of each European country, plus Russian and Turkish. One new English
source key therefore obliges a real translation in roughly thirty languages,
not two. Eleven new keys made every one of those locales lose ground at once,
and development is green, so this was my regression and not pre-existing.

The Dutch fix does not need the en.json entry. Lookup is by source string, so
`translate('Applications')` reads nl.json directly and returns "Applicaties".
en.json is the extractor's index; writing to it is precisely what triggers the
thirty-locale obligation.

So nl.json alone fixes Dutch without pretending to fix thirty languages. The
tempting alternative — copy the English value into the other twenty-nine — would
satisfy the gate and ship a lie, since an entry whose translation IS the English
reads as done to every presence check. I did that by accident on pipelinq and
had to unpick 43 of them.

Verified on this tree: check-l10n-parity PASS, test:l10n PASS, and 0 manifest
strings still missing Dutch.

* fix(l10n): rebuild nl.js, the browser loads the artifact not the JSON

`check:l10n-js` failed on this branch: I added eleven keys to l10n/nl.json and
never regenerated l10n/nl.js.

That is the failure worth naming rather than just fixing. The .json is source;
the .js is what the runtime actually loads via OC.L10N.register. A catalogue
correct in JSON and stale in JS is a translation nobody receives, and every
check that reads the JSON would have called it done. `check:l10n-js` exists
precisely because the two can disagree, and it caught this in CI on the first
run.

Same rebuild the humaniq change needed earlier today. Ran `l10n:build` rather
than hand-editing the generated file.

Verified after rebuild: check:l10n-js PASS, check-l10n-parity PASS.
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.

4 participants