Skip to content

Release: merge development into beta - #984

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

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

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 6, 2026

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.

github-actions Bot and others added 15 commits September 6, 2026 12:49
…260906124901

chore(sync): carry beta back into development
…kfill only an unambiguous match (#987)

The consolidation gave catalogContract a plain uuid pointing at shillinq's
Contract (shillinq owns contract lifecycle, ADR-066) and nothing ever
populated it. `occ stackiq:references:audit` reports the state of that link
and, with the write option, fills it in.

READ-ONLY BY DEFAULT, because a WRONG cross-app link is worse than an empty
one: an empty reference is visibly absent, a wrong one silently attributes one
contract to another. The write path fills in only an unambiguous single match
on the shared `contractNumber`, the same identity key that decided the
consolidation.

Everything else is named rather than guessed: two owners sharing a
contractNumber are ambiguous and skipped, a satellite with none is unmatched,
and a reference pointing at nothing is dangling and exits 1.

Writes go through patchObject, not saveObject/updateObject. Those two are
PUT-semantic, so a one-field update through them writes null over every
property the read did not return.

This app had no console-command mechanism at all, so info.xml grows a
<commands> block. The option name is deliberately not spelled inside the XML
comment: a double hyphen is illegal there and makes info.xml unparseable.

The command is one of four generated from a single template, so the four apps
cannot drift apart in their refusal rules. shillinq's and humaniq's halves are
verified against real data on a rig; this one is covered by its unit tests and
that shared shape, and has NOT been exercised on a live instance carrying both
stackiq and shillinq.

Verified against the BASELINE, not against zero: this app's standalone unit
config carries 20 pre-existing bootstrap errors. Before, 803 tests / 20 errors;
after, 809 tests / the same 20. PHPCS 0, Psalm 0, PHPStan 0.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
phpmd measured execute() at cyclomatic complexity 22 against a threshold of 10
and refused it. shillinq hit the same wall on the same generated shape and was
fixed in shillinq#1517; this is the equivalent, so the four apps keep one
audit shape rather than drifting.

The branching was never incidental. It is a five-way classification plus a
write decision, and naming the parts is what lets execute() read as "read,
index, audit, report": classifyRow(), auditRows(), backfill(), ownerIndex()
and report(). Behaviour is unchanged, including the ORDER the cases are tested
in, which matters — a row already carrying a reference is never a backfill
candidate regardless of what its identity key would have matched.

I did not run phpmd before pushing the first version, which is the whole
reason this exists. `composer phpmd` over all of lib/ is OOM-killed on this
box and reports a false pass, so it was run per file this time, and the exit
code was read rather than tail's.

Verified: phpmd 0 findings, PHPCS 0, Psalm 0, PHPStan 0, tests green, and
humaniq's command re-run on the rig reports the same tally as before the
refactor.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ed method (#992)

* fix(quality): name the four steps of the references audit

phpmd measured execute() at cyclomatic complexity 22 against a threshold of 10
and refused it. shillinq hit the same wall on the same generated shape and was
fixed in shillinq#1517; this is the equivalent, so the four apps keep one
audit shape rather than drifting.

The branching was never incidental. It is a five-way classification plus a
write decision, and naming the parts is what lets execute() read as "read,
index, audit, report": classifyRow(), auditRows(), backfill(), ownerIndex()
and report(). Behaviour is unchanged, including the ORDER the cases are tested
in, which matters — a row already carrying a reference is never a backfill
candidate regardless of what its identity key would have matched.

I did not run phpmd before pushing the first version, which is the whole
reason this exists. `composer phpmd` over all of lib/ is OOM-killed on this
box and reports a false pass, so it was run per file this time, and the exit
code was read rather than tail's.

Verified: phpmd 0 findings, PHPCS 0, Psalm 0, PHPStan 0, tests green, and
humaniq's command re-run on the rig reports the same tally as before the
refactor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(spec): tag the audit entry point, which gate-16 counts as a changed method

gate-16 failed the push with "1 changed method(s) missing @SPEC". The refactor
that split execute() rewrote it without carrying a @SPEC tag, and the class
tag does not satisfy a gate that asks per METHOD.

Tagged on execute() only, matching shillinq's now-passing copy of the same
command: its four helpers carry none either, so the four apps keep one shape.

Verified locally with a delta base (`--base origin/development`), which is
what gate-16 needs to judge anything at all: it now reports PASS in all three
apps. The two gates still red locally are gate-22 and gate-53 refusing to run
because ajv is not resolvable from this worktree — an honest refusal to
fail-open on a missing local dependency, not a finding, and CI has it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
hydra-gates v1.15.0 -> v1.16.0
nc-vue      2.37.0 -> 2.39.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>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.4.0 to 26.4.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.4.1
  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>
Bumps [sass](https://github.com/sass/dart-sass) from 1.103.1 to 1.104.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](sass/dart-sass@1.103.1...1.104.0)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.104.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Bumps [jest-environment-jsdom](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-jsdom) from 30.5.0 to 30.5.1.
- [Release notes](https://github.com/jestjs/jest/releases)
- [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jestjs/jest/commits/v30.5.1/packages/jest-environment-jsdom)

---
updated-dependencies:
- dependency-name: jest-environment-jsdom
  dependency-version: 30.5.1
  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>
Bumps [webpack](https://github.com/webpack/webpack) from 5.110.2 to 5.110.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)
- [Commits](webpack/webpack@v5.110.2...v5.110.3)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.110.3
  dependency-type: direct:production
  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>
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.9 to 2.2.13.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.13
  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>
)

Bumps [conduction/hydra-gates](https://github.com/ConductionNL/.github) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/ConductionNL/.github/releases)
- [Commits](ConductionNL/.github@v1.15.0...v1.16.0)

---
updated-dependencies:
- dependency-name: conduction/hydra-gates
  dependency-version: 1.16.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

EOL_DEFAULT_REGISTER still said 'openconnector'. That register was renamed to
'integriq' in the fleet rename and this default was left behind, so a default
configuration has been addressing a register nothing answers to. Integriq has
since renamed the two schemas to snake_case, so those defaults move too.

The failure mode is why nobody noticed: an unresolvable register or schema
reads as 'this module has no EOL data' and not as an error, so the sync ran,
reported success and stamped nothing.

An install whose admin opted in has the old literals STORED, where the default
never applies. RepointEolSyncConfig rewrites those, guarded on the exact stored
value so an admin pointing the feature at their own register is never touched,
and idempotent so a second upgrade changes nothing.

Two user-visible strings named the sibling app 'openconnector', including the
error shown when precisely this lookup fails. Both now name Integriq, and both
lost the em-dash the writing rules forbid.

The defaults assertion in SettingsServiceEolConfigTest documented the stale
values rather than guarding the correct ones; it now guards them, with the
reason it matters written next to it.
fix(eol): point the EOL feed at the register and schemas that actually exist
)

gate-110 fails on development:

    1 migration(s)/repair step(s) added without moving <version> in
    appinfo/info.xml, so `occ upgrade` will answer "No upgrade required."
    and run none of them

`2c3cc316` added `lib/Repair/RepointEolSyncConfig.php` and registered it
in `appinfo/info.xml`, but left `<version>` at
`0.1.152-unstable.20260901111016`. Nextcloud runs repair steps only when
the installed version moves, so as it stands the step ships, is
registered, is unit-tested, and never executes on any existing install —
and nothing reports that, because a repair step that does not run raises
nothing.

This is the failure gate-110 was written for after thirteen migrations
shipped green in this fleet having never run once.

Version moved to `0.1.153-unstable.<stamp>`. `version_compare` reads
that as greater, which is the comparison Nextcloud makes.

The EOL repoint itself is not touched — it is correct, and this is the
one thing standing between it and taking effect.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant