Audit before alpha15: the node action label stopped being translatable when it was renamed, 35 French strings sat in the wrong project's catalog, and a per-project translations job now guards them

Fixes the twelve findings of the audit on #3620175, run over 1.x at the head alpha15 will be cut from, twelve commits past 1.0.0-alpha14. Every gate was clean there, so none of this was reachable by tooling.

Configuration schema. #3618935 renamed the human-node setting act_label to action_label in the code and left orchestra.node_setting.act_label in the schema, so the live key fell through to orchestra.node_setting.* (type: string) where the named entry was type: label. label is the type core marks translatable: true, so Config Translation stopped offering the node's Action label per language while the field's own description still promised it "is translatable". A strict-config-schema test cannot see this, because the fallback gives the key a valid type; NodeSettingSchemaTest asserts the resolved type and its translatability instead, for the named key and for one the schema does not name. Seen to fail against the old schema.

Translations. Each of the 34 modules is its own interface translation project, so Drupal imports a module's file only when that module is installed. Checked per project rather than against the union of the files, 33 strings had their French filed under a project that does not contain the source; fourteen were base-module strings living only in a submodule's file, which left the kernel's own schema labels in English on a site that did not install that submodule. Every string now sits in the file of the project whose sources contain it, carrying the existing French rather than retranslating. One stale entry goes: its source wording was extended, so the old msgid is dead and the current one was already filed in the base module. A substring orphan check cannot see that, because the old text is a prefix of the new one. The three shipped inbox-view labels move to the project whose configuration carries them.

package: Workflow is left alone in the thirty files that lack it: its French is "Workflow", so an entry would produce byte-identical output and thirty lines a translator has to skip, the same reasoning as the five placeholder-only strings. Per project the module now reports zero orphans and no gaps beyond those deliberate keeps.

Documentation. Five API names no longer existed: actAccess() is checkActionAccess(), WorkItemManagerInterface is orchestra.work_item_manager in the base module rather than orchestra_inbox.manager, OrchestraReturn remembers and recalls through set() and get(), InteractionController::step() is routeToStep(), and the tenant status vocabulary resolves through orchestra.status_repository. docs/openapi.yaml documented neither limit nor offset on the instance list and described its 200 as "the matching instance summaries", so a remote consumer reading the contract expected every match and silently received one capped page; it now documents both parameters, the 1-200 clamp, the default page size, the state enum and the 400.

Comments describing code that is not there. OperationAccessCheck's class docblock said the verdict is "not cached across requests" three lines above the method that deliberately builds a cacheable one. InstanceListForm carried an orphaned comment promising a published-version cache that did not exist. A comment in CapabilityGateway that an earlier rename sweep left broken mid-sentence is rewrapped.

Performance. getPublishedVersion() was an uncached key-value read and isInstanceCurrent() calls it once per row, so the operator instance list cost fifty reads a page in manual versioning mode. The pointer is memoized per request now, behind one read path and one write path so it cannot drift from the store, and a miss is remembered as well as a hit. pruneOrphans() asked for it once per snapshot on every cron next to a revision query per snapshot; both are now one query per page of fifty. WorkflowVersioningTest proves the memo by moving the stored pointer behind the manager's back, which is the only way to show it: a kernel test runs key-value in memory, so a query budget there measures nothing.

Continuous integration. .gitlab-ci.yml claimed the module ships no CSS in a linted path and set --allow-empty-input on that basis. It ships five stylesheets and the stylelint job's own trace reads "5 sources checked, 0 problems found", so the claim and the flag are gone.

Finding 12 needs no code but does gate the tag: the Drupal 12 lane is manual, the last pipeline that ran it failed both next-major jobs under a green badge because they are allow_failure, and nothing had run it since. Played on this head it is green (227 classes, 990 passed, 0 failed, 5 classes fully skipped, all five the documented skipWithoutDrupal12() set). Worth playing and reading again before alpha15 is tagged rather than assuming.

Locally: phpcs over 941 files clean, PHPStan level 5 clean, cspell clean on every changed file, and the five kernel classes that touch the changed paths green. Both new assertions were seen to fail against the unfixed code.

Edited by Frank Mably

Merge request reports

Loading