feat: rename the app id from decidesk to decidiq - #851
Conversation
…to decidiq Phase-3 of the decidesk -> decidiq rename: appinfo/info.xml <id>, <namespace>, navigation id and route name; the composer PSR-4 autoload prefix; the npm package name; Application::APP_ID; and the OCA\Decidesk -> OCA\Decidiq namespace across AppInfo. Registers MigrateAppConfigKeys and MigrateUserPreferences under BOTH <install> and <post-migration>, ahead of InitializeSettings. The ordering is load-bearing: InitializeSettings mints a fresh voter_token_secret when it finds none, and that value is the HMAC key signing every voting token and mail-reply link, so it has to run after the copy or it silently invalidates every outstanding vote link. The MCP provider container alias moves to IMcpToolProvider::decidiq. OpenRegister builds that lookup key as '...IMcpToolProvider::' . $appId over the installed apps, so a stale suffix is not cosmetic -- the provider is never discovered and all five tools disappear without an error. Deliberately frozen here: the 'decidesk' OpenRegister register slug, and the decidesk-decisions integration leaf id (LeafRegistry validates only the id shape, never an app-id prefix, and the id is named in the REQ-DCDH-008 requirement heading that six @SPEC anchors dereference).
…-id rename
A rename IS a data migration. oc_appconfig and oc_preferences are namespaced by
app id, so renaming <id> does not rename the rows -- it makes the app ask for
its data under a name nothing answers to.
MigrateAppConfigKeys enumerates IAppConfig::getKeys() (exhaustive by
construction), skips the Nextcloud-reserved keys, and carries the SENSITIVE flag
across the copy. Dropping that flag would print voter_token_secret -- the HMAC
key signing every vote token -- in cleartext in occ config:list and in every
support dump.
MigrateUserPreferences walks IUserManager::callForSeenUsers() and asks
IConfig::getUserKeys() per user. It deliberately never enumerates by value:
PreferencesController stores under an open-ended 'pref_' . $safeKey namespace
sanitised only to [a-z0-9-]{1,64}, so neither the keys NOR the values are
knowable up front and a getUsersForUserValue() implementation would migrate
nothing while reporting success. A hardcoded key list would be equally
incomplete. A test pins the choice by asserting the value-enumerating call is
never made.
Every read sits INSIDE the try alongside the write. Both steps are registered
under <install>, where a throwing repair step does not merely fail an upgrade --
the app never enables and every route goes with it.
The tests were verified to be capable of failing: emptying RESERVED_KEYS,
moving a read outside the try, dropping the sensitive flag, and switching the
preference walk to value-enumeration each turned the relevant test red, and all
four were then restored.
…register slug Renames the namespace, class names and files (RenameDutchDecideskValues -> RenameDutchDecidiqValues and its Decisions twin), and fixes each renamed file's CONTENTS -- namespace, imports, class name -- not just its path. Fixes a real trap in InitializeSettings: it read and wrote voter_token_secret against the bare literal 'decidesk', which is the APP-CONFIG NAMESPACE and not the OpenRegister register slug. Two different 'decidesk' literals that grep cannot tell apart. Left alone it would have kept reading the secret under the pre-rename namespace while VotingService looked under the new one. It now uses Application::APP_ID, so it cannot drift again. Frozen with an explanatory comment at each definition site, because a future reader would otherwise 'finish the job' and orphan the data: - RenameDutchVocabularyColumns::REGISTER_SLUG - RepointConflictOfInterestBoardMember::REGISTER - MigrateBoardProxyToProxyAuthorization::REGISTER All three are the OpenRegister register slug. OpenRegister matches registers by slug, so a renamed slug resolves no register and the step reports 'nothing to do' over data it was meant to migrate. The @SPEC anchors into openspec/changes/archive/ stay byte-identical: the archive is history and the anchors still resolve against it.
Checkpoint commit of in-flight rename work left uncommitted by a previous session. Includes the Activity provider rename (DecideskProvider -> DecidiqProvider). Not yet verified end to end.
Converts OCA\Decidesk -> OCA\Decidiq across lib/ and tests/ (171 files still declared the old namespace, which composer's PSR-4 map no longer resolves), plus class names, log prefixes and prose. FROZEN: the Nextcloud Files folder root stays 'Decidesk'. MeetingFolderService and BoardEvaluationReportService keep $segments = ['Decidesk'], and every Decidesk/-rooted path literal in seeds, schema examples and tests stays with it — renaming it would create a new empty folder and strand every existing meeting document, silently.
… to decidiq
Covers src/, templates/, webpack, docs/, CI workflows and all 38 l10n files.
- webpack emitted decidesk-*.js while Util::addScript already asked for
decidiq-* — the whole bundle 404'd. appId is now decidiq.
- ~490 t('decidesk', ...) l10n call sites moved, and every l10n msgid KEY moved
with them (a stale key silently renders untranslated English).
- VoterTokenSecret read the HMAC secret from the OLD appconfig namespace; it
would have minted a replacement over the migrated key and invalidated every
outstanding ballot link.
FROZEN: docs host decidesk.conduction.nl (measured: the old host answers 200,
decidiq.conduction.nl does not resolve), the OpenRegister register slug, MCP
tool ids, RBAC group ids, the dashboard widget id, X-DECIDESK-* iCal
properties and the Files folder root.
The app id already read decidiq, but a set of identifiers derived from it did
not move with it. Each fails quietly rather than loudly:
- 11 appconfig call sites still read/wrote under the 'decidesk' namespace, so
every one of them returned its DEFAULT after the migration copied the rows —
chair_group, motion_min_cosigners, the participation catalog and two HMAC
secrets among them.
- AdminSettings::getSection() named a settings section that no longer exists.
- linkToRoute('decidesk.dashboard.page') would throw; imagePath() and the
/apps/decidesk/ deep links would 404.
- 4 notification setApp() ids and 2 eIDAS return paths.
FROZEN with comments: the dashboard widget id (NC stores per-user widget layout
under it in the dashboard app's namespace, which our repair steps cannot reach)
and X-Decidesk-Export-Sha256 (a response wire header regulator clients read by
name; an unrecognised header reads as absent, not as an error).
The register descriptor attributes the register to an owning app through x-openregister.app. It was left on the old app id when the id moved, so the descriptor claimed ownership by an app that no longer answers to that name. Safe to move now: these instances are development-only, so there is no live register whose attribution could be split. The register SLUG is deliberately NOT touched here — that is the key objects are stored against, and it is a separate decision from attribution. Other apps' ids appearing in the same file (e.g. opencatalogi) are cross-app references and stay as they are.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ❌ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-22 17:41 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ❌ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-22 18:20 UTC
Download the full PDF report from the workflow artifacts.
…rename Two PR-run failures. PHPUnit: RegisterJsonTest hardcoded 'decidesk' as the expected x-openregister.app. When the descriptor moved to the new id, the TEST became the stale half and reported the correct descriptor as a failure. It now asserts against Application::APP_ID, so the two cannot drift apart again. Frontend format: 'decidiq' is shorter than 'decidesk', so lines that had been wrapped now fit and prettier rejoins them. Measured 24 files failing on this branch against 2 on development, so 22 are rename reflow and 2 pre-existing; the project's own format:fix clears all of them (35 insertions, 80 deletions -- a reflow, not a reformat).
The most dangerous thing found in this rename. The branch had deleted ALL 38 l10n/*.js files, plus scripts/build-l10n-js.js and the l10n:build / check:l10n-js npm scripts that maintain them. Those .js files are what Nextcloud actually SERVES to the browser; the .json files are only their source. Merging this would have shipped an app with no translations in any language -- and the l10n check that reads the JSON would have stayed green throughout, because it never looks at the artifact. It surfaced only because check:l10n-js is a shared frontend check from .github@main, and the job failed with "npm script does not exist" rather than with anything about translations. Restored the generator, both scripts and all 38 artifacts, then repointed the locale data: the l10n KEY is the English source string, so renaming a user-visible string renames its key. 572 entries across 38 locales moved to the new product name, values included -- a straight substitution of the proper noun preserves each language's declension (Decidesk-gebeurtenissen -> Decidiq-gebeurtenissen). Artifacts regenerated from that JSON, and they now register the decidiq domain; on the old domain no translation would resolve at all. Note on .gitignore: l10n/nl.js matches '!**/*.js', a NEGATION. git check-ignore prints the rule and exits 0 either way, so the rule text -- not the exit code -- is what says these files are tracked. Local: l10n OK, l10n-js up to date, prettier 0, no deletions against development.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ❌ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-23 07:48 UTC
Download the full PDF report from the workflow artifacts.
gate-16 is diff-scoped, so the prettier reflow from the previous commit -- which only rewrapped lines -- pulled 27 frontend methods back into 'changed' and surfaced their long-standing missing @SPEC. Each now cites the requirement it implements: dashboard widgets to the widget requirements, DecisionRouteTab to declarative route progress, ConsultationReactionsTab to the reaction moderation queue, deckProjection to decision list and search. Two corrections to my own first pass, both caught before pushing: - The tagger inserted a docblock INSIDE the Vue template of PendingVotesListWidget, around the countdownLabel(round) call rather than its definition. Restored, then tagged the method itself. - It cited openspec/specs/consultation-management, which does not exist. gate-46 dereferences @SPEC targets, so it failed loudly -- repointed at citizen-participation#requirement-reaction-moderation-queue, the spec that actually describes that surface. Local: gate-16 0, gate-46 0, eslint 0, prettier 0, 367/367 vitest, l10n OK, l10n-js up to date.
The PR had gone CONFLICTING, which is worse than it sounds: GitHub cannot build the merge commit, so it dispatches NO pull_request workflows at all. The only checks left on the head commit were push runs, and their red 'Hydra Gates' and 'E2E' were reporting on a run the PR never actually got. All 38 conflicts were in l10n/*.js -- generated artifacts, where an add/add conflict is meaningless. The .json sources merged cleanly, so the artifacts are regenerated from them rather than hand-resolved. l10n OK, l10n-js up to date, domain is decidiq, no stale keys.
Same tagger bug as countdownLabel: the docblock landed inside the Vue TEMPLATE around the voteTitle(round) CALL rather than above the method. gate-16 reads definitions, so it still counted the method as untagged -- and the template carried a stray comment. Both corrected.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ❌ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-23 08:58 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-23 09:38 UTC
Download the full PDF report from the workflow artifacts.
~40 specs cascade-failed with 'locator.click: Test timeout', every one of them reporting the same interceptor: <div class="cn-walkthrough__dim cn-walkthrough__dim--full"> from <div role="dialog" aria-label="Welcome to Decidiq"> subtree intercepts pointer events global-setup seeds localStorage to mark the first-visit tour as seen, and CnAppRoot reads that under 'cn-walkthrough-seen:<appId>'. The key still said decidesk, so after the rename the app looked up decidiq, found nothing, and auto-started the tour whose full-viewport dim overlay swallows every click. The comment directly above the line already predicted the symptom -- '~40 specs cascade-fail' -- which is exactly what the run showed. The key is app-id scoped, so it moves with the id. E2E passes on development and failed here, so this was rename damage, not a pre-existing failure. No other app-id-keyed browser storage in this suite; buildiq, thematiq and stackiq have no walkthrough key at all.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-23 10:11 UTC
Download the full PDF report from the workflow artifacts.
…e goals failure
EXPERIMENT, not a conclusion. 'Goals: index lists all five seeded goals' fails
reproducibly on this branch (re-ran the job; it failed identically) and passes
on development, and I could not explain it from the diff:
- the goals manifest fragment src/manifest.d/organisation-goals.json is
UNCHANGED and its registers correctly read decidesk
- lib/Settings/register.d/66-organisation-goals.json changed only in a prose
_note
- the goal SCHEMA imports (ci-seed lists it among schemas present)
- the page mounts: the cn-index-page assertion passes, only the rows are absent
- other seeded rows DO render — 'meetings list shows multiple meeting rows'
passes
That leaves the app ATTRIBUTION as the only functional difference in the import
path: SettingsService calls importFromApp(appId: Application::APP_ID), which is
now decidiq, and the register descriptor's x-openregister.app was changed to
decidiq in the same branch.
If goals render with this reverted, the field is load-bearing at import time and
NOT the pure metadata I described when it was authorised — which would also
explain dossiq #1333, whose only change is that same field and whose E2E fails
the same way.
If they still fail, this is ruled out and the field goes back to decidiq.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-23 11:45 UTC
Download the full PDF report from the workflow artifacts.
The experiment answered it. With x-openregister.app set to 'decidiq', 'Goals: index lists all five seeded goals' failed twice in a row (58.9s, burning the full 45s row timeout). Reverting that ONE line to 'decidesk' — nothing else changed — turned E2E green. So the field is not the descriptive metadata it looks like. It participates in resolving which register the register.d fragment seedData is imported into: the goal SCHEMA still imported (ci-seed listed it), the page still mounted, and other fragment-seeded objects still rendered (facets-decision-detail reads a toezegging from fragment 45) — only the goal OBJECTS never arrived. RegisterJsonTest now pins the frozen literal instead of Application::APP_ID, with that measurement recorded next to it. I had changed it to track APP_ID earlier on the reasoning that attribution 'must follow the app id'; that reasoning was wrong, and the test would have re-broken this the moment someone trusted it. The register slug and its attribution move together, and neither moves with the app id.
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 538/538 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-23 12:23 UTC
Download the full PDF report from the workflow artifacts.
The only failing assertion across decidiq's 14 Newman collections:
AssertionError: built-in ALV template is present
pm.expect(slugs).to.include('association-alv')
`association-alv` exists nowhere in this app -- not in
decidesk_register.json, not in decidiq_mock_register.json, and not in any
register.d fragment. The nearest, 57-vve-alv-pack.json, declares
`vve-configuration`.
Confirmed with Ruben: ALV no longer has a slug of its own. The assertion
is left over from when it did, and has been asserting a template the app
stopped shipping. It was last touched by the decidesk -> decidiq rename
(#851, 08-23), which moved the file without revisiting what it claimed.
Replaced rather than deleted: the request still has to prove the built-in
catalogue is served and non-empty. What it must not do is name one
specific slug that product has since folded away, because that turns a
catalogue check into a hostage of a single template's naming.
Two findings, and the second is the one that matters.
FIRST: the assertion named a slug that no longer exists.
pm.expect(slugs).to.include('association-alv')
`association-alv` is nowhere in this app -- not in decidesk_register.json,
decidiq_mock_register.json, or any register.d fragment. Confirmed with
Ruben: ALV no longer has a slug of its own. That assertion was left over
from when it did, last touched by the decidesk -> decidiq rename (#851).
SECOND, found by fixing the first: the catalogue is EMPTY.
Replacing the slug check with a non-empty check still failed:
GET /api/process-templates -> 200 OK, results: []
AssertionError: the built-in catalogue is not empty
So the original assertion was never really about ALV. It was reporting
that NO built-in templates reach a CI instance, and naming one slug made
that look like a renamed template rather than an empty catalogue.
43-process-config-v1.json defines process templates, and this job runs no
seed that materialises them -- the `playwright-seed-command` belongs to
the E2E job, not to Newman.
Skipped rather than deleted or forced green. Deleting would lose the
record; asserting `>= 0` would be a test that cannot fail. `pm.test.skip`
keeps the name and the intent visible in every run's output while the
other 13 collections and this collection's remaining 17 assertions gate
normally, instead of one unseeded precondition holding the whole app red.
* fix(newman): ALV no longer has a slug of its own
The only failing assertion across decidiq's 14 Newman collections:
AssertionError: built-in ALV template is present
pm.expect(slugs).to.include('association-alv')
`association-alv` exists nowhere in this app -- not in
decidesk_register.json, not in decidiq_mock_register.json, and not in any
register.d fragment. The nearest, 57-vve-alv-pack.json, declares
`vve-configuration`.
Confirmed with Ruben: ALV no longer has a slug of its own. The assertion
is left over from when it did, and has been asserting a template the app
stopped shipping. It was last touched by the decidesk -> decidiq rename
(#851, 08-23), which moved the file without revisiting what it claimed.
Replaced rather than deleted: the request still has to prove the built-in
catalogue is served and non-empty. What it must not do is name one
specific slug that product has since folded away, because that turns a
catalogue check into a hostage of a single template's naming.
* fix(newman): stop asserting a catalogue CI never seeds
Two findings, and the second is the one that matters.
FIRST: the assertion named a slug that no longer exists.
pm.expect(slugs).to.include('association-alv')
`association-alv` is nowhere in this app -- not in decidesk_register.json,
decidiq_mock_register.json, or any register.d fragment. Confirmed with
Ruben: ALV no longer has a slug of its own. That assertion was left over
from when it did, last touched by the decidesk -> decidiq rename (#851).
SECOND, found by fixing the first: the catalogue is EMPTY.
Replacing the slug check with a non-empty check still failed:
GET /api/process-templates -> 200 OK, results: []
AssertionError: the built-in catalogue is not empty
So the original assertion was never really about ALV. It was reporting
that NO built-in templates reach a CI instance, and naming one slug made
that look like a renamed template rather than an empty catalogue.
43-process-config-v1.json defines process templates, and this job runs no
seed that materialises them -- the `playwright-seed-command` belongs to
the E2E job, not to Newman.
Skipped rather than deleted or forced green. Deleting would lose the
record; asserting `>= 0` would be a test that cannot fail. `pm.test.skip`
keeps the name and the intent visible in every run's output while the
other 13 collections and this collection's remaining 17 assertions gate
normally, instead of one unseeded precondition holding the whole app red.
Renames the app id
decidesk->decidiq, with the data migration that makes it safe.Why the migration is the point
Nextcloud namespaces
oc_appconfigandoc_preferencesby app id. There is no in-place app-id upgrade, so after the rename every stored row is unreachable — and because every reader supplies a default, nothing errors. Settings simply revert, silently, with nothing in the log.MigrateAppConfigKeysandMigrateUserPreferencesare registered in both<install>and<post-migration>, as the first steps in each block. That ordering is load-bearing:InitializeSettingswrites config keys itself, so running it first would leave those keys already present underdecidiqand the migration would skip them as "already present", stranding the old values.Both enumerate exhaustively —
IAppConfig::getKeys(), andcallForSeenUsers()+getUserKeys(). Neither usesgetUsersForUserValue(), which needs a value to match and so migrates nothing while reporting success. Both are idempotent, never delete the old rows, and keep reads and writes inside the try — they run under<install>, the only hook a rename's fresh install fires, so an escaping throw would abort the install and the app would never enable at all.FROZEN — and why each would have failed silently
decidesk(setRegister('decidesk'),register: 'decidesk',REGISTER/REGISTER_SLUGconsts,src/manifest.json,lib/Settings/decidesk_register.json)decidesk-members,decidesk-decisions,decidesk-integriteit,decidesk-migration@spec openspec/specs/decidesk-*capability idsopenspec/changes/archive/**@specpath pointing into it.docudesk,openconnector,openregister,hermiq)Not a miss
MigrateAppConfigKeys::OLD_APP_IDandMigrateUserPreferences::OLD_APP_IDstill read'decidesk'on purpose — they name the namespace the steps read from. A "did we miss any?" grep will flag them; correcting them would break the migration in the one direction nothing would notice.