Skip to main content

App health

Live Code Quality status for every Conduction Nextcloud app, on each of the three branches it ships through. Badges come straight from GitHub Actions and update themselves — click one to open that branch's runs.

Nextcloud apps​

Every app is checked by the same Code Quality workflow. Category is the role an app plays in the fleet; Type is its domain.

AppCategoryTypeLatest releasemainbetadevelopment
decidiqApplicationDecision-making2026-08-17mainbetadevelopment
filinqApplicationDocuments2026-08-17mainbetadevelopment
larpinqApplicationLARP management2026-08-17mainbetadevelopment
opencatalogiApplicationCatalogue2026-08-10mainbetadevelopment
pipelinqApplicationCRM2026-08-18mainbetadevelopment
portaliqApplicationClient portal2026-08-17mainbetadevelopment
dossiqApplicationCase management2026-08-17mainbetadevelopment
learniqApplicationLMS / LVS2026-08-18mainbetadevelopment
shillinqApplicationBusiness admin2026-08-17mainbetadevelopment
stackiqApplicationCatalogue2026-08-17mainbetadevelopment
humaniqApplicationHR & payroll2026-08-12mainbetadevelopment
launchpadFrameworkDashboards2026-08-08mainbetadevelopment
buildiqFrameworkLow-code builder2026-08-17mainbetadevelopment
thematiqFrameworkDesign system2026-08-17mainbetadevelopment
keepiqPlatformSecrets management2026-08-18mainbetadevelopment
hermiqPlatformAI / agents2026-08-18mainbetadevelopment
integriqPlatformIntegration / ESB2026-08-18mainbetadevelopment
openregisterPlatformObject store2026-08-10mainbetadevelopment
versioniqToolingApp lifecycle2026-08-12mainbetadevelopment
nextcloud-app-templateScaffoldProject template2026-04-13mainbetadevelopment

Deprecated apps​

Still in the repository and still building, but not being taken forward. They stay listed because a deprecated app that disappears from the dashboard becomes an app nobody is measuring. Red here is informational: check whether the work is wanted before greening a row in this table.

AppCategoryTypeLatest releasemainbetadevelopment
planninqApplicationProject management2026-08-03mainbetadevelopment
zaakafhandelappApplicationCase management2024-10-23mainbetadevelopment

Renaming​

Apps are being renamed onto a common suffix. Both names appear in the wild during a rename — the repository, the appinfo/info.xml id, the OpenSpec directory and the App Store listing do not all move on the same day — so this table is the mapping of record.

⚠️ A rename is a data migration, not a find-and-replace. The app id appears in appinfo/info.xml, route names, OpenRegister register slugs, app-config keys, and any object already written under the old id. Renaming the repository alone leaves live data pointing at a name nothing answers to.

Renaming an app is the procedure: the three phases, which stores the app id keys, the repair steps that carry data across, and the per-user preference that reverts silently if you forget it.

Old nameNew nameStatus
mydashlaunchpaddone — the mydash repo is archived; treat any surviving reference as stale
scholiqLearniqrepo renamed — app id pending
nldesignThematiqrepo renamed — app id pending
hrmqHumaniqrepo renamed — app id pending
decideskDecidiqrepo renamed — app id pending
larpingappLarpinqrepo renamed — app id pending
openbuildBuildiqrepo renamed — app id pending
procestDossiqrepo renamed — app id pending
docudeskFilinqrepo renamed — app id pending
doriathKeepiqrepo renamed — app id pending
softwarecatalogStackiqrepo renamed — app id pending
openconnectorIntegriqrepo renamed — app id pending
app-versionsVersioniqrepo renamed — app id pending
planixPlanninqrepo renamed — app id pending; repo is in deprecated in fleet-apps.json. Not Planiq: that name collides with Anaplan's trademarked PlanIQ™, so the -inq form was taken instead
OpenAnonymiserAnonymiqrepo renamed — app id pending
financeqAccountinqplanned
purchaseqPurchasinqplanned

Unchanged by decision (2026-08-21): launchpad, pipelinq, shillinq (the coin, never "Shellinq"), hermiq, portaliq, openregister, opencatalogi, openwoo, nextcloud-vue, nextcloud-app-template, and the ExApp sidecars. zaakafhandelapp and deskdesk are discontinued and get no new name.

Until a row reads done, the old name is the one that resolves — the badges above and every gh command still use it.

Libraries​

Not Nextcloud apps, but every app depends on them, so a regression here reaches the whole fleet.

RepositoryPackageKindVersionmainbetadevelopment
nextcloud-vue@conduction/nextcloud-vueVue component library2.4.0mainbetadevelopment
design-system@conduction/docusaurus-presetDocusaurus preset3.28.0no Code Quality workflow
docusaurus-plugin-portaliqdocusaurus-plugin-portaliqDocusaurus plugin—no Code Quality workflow
coding-standardconduction/coding-standardPHP coding standard—no Code Quality workflow
.githubconduction/hydra-gatesQuality gate suite—no Code Quality workflow

Only nextcloud-vue runs the shared Code Quality workflow. The other four are checked by their own workflows or not at all — which is worth knowing before treating a blank cell as healthy.

⚠️ @conduction/docusaurus-preset still declares a Codeberg repository URL in its npm metadata. Codeberg is retired; the live source is ConductionNL/design-system.

Lifecycle and support​

Every app release is tied to a Nextcloud version — the one current at its launch — though a release may still support lower versions. That anchor is what the support window is measured from.

GuaranteeWindow
Bug fixes2 years
Security fixes (CVE)5 years

When a release happens relative to Nextcloud​

The fleet runs two-week phases, so a beta is always one phase ahead of its stable release.

CategoryStable releaseBeta available
Platform appsthe day Nextcloud releases2 weeks before the Nextcloud release
Application appsthe week after Nextcloud releases1 week before the Nextcloud release

Platform apps go first on purpose: application apps are thin clients over openregister and openconnector, so the layer underneath has to be on the new Nextcloud version before the layer above can be.

Application releases are normally minor — a new Nextcloud version is not by itself a reason for a breaking change.

A five-year CVE window tied to a launch-time Nextcloud version means an app released today is still receiving security fixes long after that Nextcloud version leaves upstream support. Check the anchor version before assuming an old install is out of scope: the app's clock started at its launch, not at Nextcloud's end-of-life.

Friday automation​

Every Friday at 08:00 Europe/Amsterdam, per app:

  1. Merge outstanding development pull requests whose checks are fully green
  2. Open development → beta; when green, merge it
  3. Release

Green means green. Not parity with a red base, not "only the usual failures" — a pull request merges unattended only when every check has a verdict and none of them failed. A pending check is not a pass, and an unreadable response is not a pass either; both mean skip and report.

Anything the routine skips is logged with its reason. A silent skip is indistinguishable from a merge that happened, and a routine you cannot audit is a routine you cannot trust to run while nobody is watching.

⚠️ The clock is UTC. GitHub cron has no time-zone support, so 08:00 Dutch is 06:00 UTC in summer and 07:00 UTC in winter. A fixed cron drifts an hour twice a year; the schedule is set in UTC and the job checks local time before acting, rather than pretending the drift does not exist.

Status: built, and blocked on one secret. This section described intent rather than behaviour for long enough that someone read the page and reasonably believed the fleet was being merged every Friday. It is now three workflows, each of which refuses loudly rather than reporting a routine that measured nothing:

workflowFriday (UTC)what it does
fleet-drift-sweep.yml06:00re-runs Code Quality on development for every app, and fails when any app is not green
fleet-cve-release.yml06:30merges Dependabot security fixes, classified against GitHub's own alerts
fleet-friday-merge.yml07:00merges development pull requests that are genuinely green

⚠️ None of them can run until FLEET_DISPATCH_TOKEN exists. It is an org-level secret needing contents: write, pull-requests: write and security-events: read on every repo in fleet-apps.json; GITHUB_TOKEN is repository-scoped and cannot reach another repo. All three assert it first and exit 1 — verified by dispatching them, which failed at exactly that step with everything downstream skipped.

Two things are deliberately not automated, and are gaps rather than oversights:

  • Promotion past development. Shipping a CVE by promoting development → beta → main would release the whole unreleased backlog — measured 2026-08-19, openregister's development is 3,238 commits ahead of beta and 5,454 ahead of main. One dependency bump would carry thousands of unreviewed functional commits through the protection this is allowed to cross only for CVEs.
  • Release. It waits on a dry run being read against real pull requests. An unattended release is not where you discover that a lockfile cherry-pick conflicts.

The merge routine would not have caught gate drift​

Merging green pull requests is not the same as knowing the fleet is still compliant, and it is worth being explicit about why.

A green badge is a verdict about a moment, not a state. The gates are consumed at @main, so a stricter gate reaches every app the instant it merges — but a gate only produces a verdict when a workflow runs, and app workflows run on push and pull_request only. An app nobody has touched keeps the green badge it earned under the old gates. Tighten a gate on Friday and the fleet is non-compliant and green at the same time, until somebody happens to push.

Measured 2026-08-19: of 21 swept apps, exactly one (pipelinq) had any scheduled run at all. The other twenty could only be re-measured by hand.

So a separate fleet drift sweep re-runs Code Quality on development for every app, Fridays at 06:00 UTC — .github/workflows/fleet-drift-sweep.yml, iterating fleet-apps.json.

⚠️ It cannot be a cron inside each app, and the reason is easy to get wrong. GitHub runs a scheduled workflow from the repository's default branch and gives you no way to choose a ref. The fleet's defaults are split — measured 2026-08-19, 11 apps default to development and 10 to main — so copying pipelinq's cron everywhere would measure main on ten of them. main is stale-red across much of the fleet, so those ten would go red for reasons that have nothing to do with drift. workflow_dispatch does take a ref, which is why the sweep is central and passes --ref development explicitly.

🔴 The badges above cannot see the sweep — read the sweep run instead​

The sweep's first draft stopped at dispatching, on the reasoning that each app's own Quality Report decides and the badges above show the result. Measured 2026-08-19, that is false, and it matters: it would have rebuilt the same silent failure one layer down.

Every badge on this page carries &event=push:

…/code-quality.yml?branch=development&event=push&label=development

A sweep produces workflow_dispatch runs, so shields.io does not look at them at all — the badge keeps showing the last push verdict. Positive control on pipelinq/development, which proves the filter is live rather than inert:

QueryNewest run it sees
?branch=development&event=pushpush — success
?branch=developmentpull_request — failure

So an app could fail every gate in the Friday sweep and stay green on this page.

Dropping &event=push is not the fix. Unfiltered, the newest run on a branch is frequently a pull_request run of a PR merge ref — a verdict about a proposal, not about the branch, exactly as the control above shows.

Instead the sweep's collect job waits for every dispatched run and fails when any app is not success, with a per-app table in its run summary. One red run covers the whole fleet, and — unlike a badge — it cannot go green by having measured nothing: cancelled, no run appeared and still running at deadline are each reported as red, never folded into a pass.

A second badge column keyed on event=workflow_dispatch is the natural follow-up (an app with no dispatch run renders a grey no status, not a false red — verified against nextcloud-app-template, which has none). It is not added yet: every app already carries unrelated manual dispatch runs — openregister's newest is from 2026-08-11 and failed — so the column would open showing week-old verdicts as though they were this Friday's. Add it once the first sweep has given every app a dispatch run that means what the column claims.

Status: the workflow exists; it needs a token. It requires an org-level FLEET_DISPATCH_TOKEN with actions: write on every repo in fleet-apps.json — GITHUB_TOKEN is repository-scoped and cannot dispatch elsewhere. The job asserts the token first and fails loudly when it is absent, rather than being refused 21 times and reporting a green sweep that measured nothing.

Monday automation — keeping the shared dependencies current​

The Friday sweep re-measures the fleet. It does not move it. Two packages every app depends on drift on their own, and nothing carried them:

measured 2026-08-20available
conduction/hydra-gates17 of 17 apps on v1.8.0v1.8.1
@conduction/nextcloud-vue14 of 17 below 2.7.0 (12 on 2.3.0)2.8.2

⚠️ Nothing there was pinned on purpose. Both are declared with caret ranges that already permitted the newer releases. What froze them is the lockfile, which nobody re-resolves unless they happen to be touching dependencies that day. Neither number was a decision; both were the absence of one.

The cost was not theoretical. hydra-gates v1.8.0 shipped an ObjectServiceInterface without patchObject(), and because the package used to claim OCA\OpenRegister\Contract\ in its composer autoload — a longer psr-4 prefix than openregister's own — a stale copy in any app's vendor directory defined that contract for the whole instance. Measured: softwarecatalog's vendor was supplying openregister's interface.

✅ That mechanism is gone. The prefix was removed from the package (ConductionNL/.github#531); the contracts still ship, but a consumer now opts in from its own test bootstrap behind interface_exists(), which is order-independent. Four apps needed the opt-in — buildiq, decidiq, filinq and stackiq. The others either ship their own contract stubs (dossiq, pipelinq, shillinq), own the real one (openregister), or never reference it.

Separately, nc-vue's AI-companion singleton landed in 2.7.0, so every app below it rendered a second companion hex beside hermiq's on every page. Both fixes had existed upstream for weeks.

So a fleet shared-dependency bump runs Mondays at 05:00 UTC — .github/workflows/fleet-shared-dep-bump.yml, iterating the same fleet-apps.json. Monday deliberately, and earlier in the week than the sweep, so a bump that turns an app red has the week to be noticed rather than being discovered by Friday's measurement.

It cannot be a cron inside each app, for the same reason the sweep cannot — see above.

It opens pull requests; it does not push, and it never force-pushes​

A shared bump is not always safe, and CI is what knows. Taking hydra-gates v1.8.1 added patchObject() to a published interface, which is a load-time fatal for any concrete test double implementing it without the method — Class … contains 1 abstract method and must therefore be declared abstract. The suite dies before a single test runs. Two apps needed stub updates before they could take the bump at all. A workflow that pushed straight to development would have broken them silently.

🔴 And it must never force-push. The first draft reused one long-lived branch per app and force-pushed it weekly. That destroys work: the PR body invites a maintainer to fix a broken bump on that branch, and the next Monday run would have overwritten the fix without a trace. So:

  • if a bump PR is already open for an app, the run skips that app entirely and says so — an app already being dealt with is not a candidate;
  • when it does push, it pushes a new dated branch, never a reused one.

It touches composer.lock / package-lock.json only. composer.json and package.json are never rewritten, so a bump cannot silently widen what an app declares it accepts.

Status: the workflow exists; it needs a wider token. It reuses FLEET_DISPATCH_TOKEN, but needs contents: write and pull-requests: write on the app repos where the sweep only needed actions: write. It asserts the token first and fails loudly when it is absent; if the grant is merely too narrow it fails at the push step, and the run summary names that as the likely cause rather than leaving a blank row.

Release schedule​

App Store on Friday, social announcement the following Monday. After the first two slots the cadence is one app every two weeks.

DateApp Store (Fri)Social (Mon)Apps
Week of 17 Aug2026-08-212026-08-24openregister, keepiq, nextcloud-vue
Week of 24 Aug2026-08-282026-08-31hermiq, buildiq
+2 weeks2026-09-112026-09-14pipelinq
+2 weeks2026-09-252026-09-28portaliq
+2 weeks2026-10-092026-10-12dossiq
+2 weeks2026-10-232026-10-26filinq
+2 weeks2026-11-062026-11-09thematiq

Every date above is a Friday, verified. The Latest release column in the tables is the last GitHub release, which is not the same thing as an App Store publication — an app can have shipped a dev tag today and still be weeks from its store slot.

Not on this page, and why​

Solutions, not apps. OpenWoo and openanonymiser are products assembled from several repositories rather than a single Nextcloud app, so there is no one Code Quality badge that represents them. OpenWoo alone spans OpenWooApp (archived), openwoo-app-website, openwoo-app-config and the woo-website-* family. Badging one repo of a solution would report on a part while reading as the whole.

Archived repositories are excluded.

How this list is built​

Membership comes from two checks, not from a hand-maintained list: the app appears in the public site's apps-catalog.js, and the repository carries appinfo/info.xml on its default branch — the canonical marker of a Nextcloud app.

That matters. A hand-maintained fleet list previously omitted seven live apps, and one of them carried well over a thousand outstanding gate findings while going entirely unmeasured, because nothing swept an app that wasn't on the list. Building this page from the catalog immediately surfaced planix, a Nextcloud app running Code Quality that the working fleet list did not include. It is now listed under Deprecated apps — which is the point: it went unmeasured for months precisely because no list carried it, and "deprecated" is a reason to record an app, not to drop it.

This page is the list of record. If an app is not on it — active, deprecated, or excluded with a reason below — it is not being measured by anybody. Add the row before you need it.

Archived repositories are excluded.