Commit Graph
14682 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5.5 78c526d759 Merge remote-tracking branch 'origin/main' into HEAD
roles/web-app-n8n/meta/services.yml conflicted on the n8n pin: main already
carries 2.43.4 from #900, newer than this branch's 2.43.2, so main's side is
kept. The provisioning fixes of this branch are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:56:57 +02:00
kevinveenbirkenbachandClaude Opus 5.5 24d7872fde Merge remote-tracking branch 'origin/main' into HEAD
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:54:31 +02:00
infinito-nexus-updater[bot] beb8d0a66b update(images): update Docker image versions (web-svc-onlyoffice) 2026-10-12 16:52:45 +00:00
kevinveenbirkenbach fe0f6c16d9 Merge pull request #896 from infinito-nexus/update/docker-image-versions-web-app-socialhome-20261012-3f49801
update(images): update Docker image versions (web-app-socialhome)
2026-10-12 18:36:47 +02:00
kevinveenbirkenbachandClaude Opus 5.5 e31b9557d2 fix(env): keep the host .env when the runner container runs make setup
The repository is bind-mounted into the infinito container, and every deploy
runs `make setup` there, which depends on `dotenv`. The generator therefore
rewrote the host's .env with the values the container sees: the host lost
INFINITO_RUNNING_ON_GITHUB=true that way, and the guide replay pulled
alpine:latest past the GHCR mirror.

compose.yml now marks the infinito service with INFINITO_DOTENV_HOST_OWNED,
and `python -m cli.meta.env` keeps an existing .env while that marker is
"true". A missing .env is still generated, and `make dotenv-force` (env -i)
still rewrites it. The key stays out of the env registry: only compose.yml
sets it, it is no configuration value, and a .env entry could freeze the
host .env.

test_distros now also strips INFINITO_ENV_LOADED. load.sh returns early
while that guard is set and the mtime of .env is unchanged, so the test only
reloaded the budget keys it strips because the container kept rewriting .env.

Verified: unit tests cover a kept .env, a missing one being generated, and a
rewrite without the marker. Local compose deploys print "Kept .env: the host
checkout owns it" where they printed "Wrote .env" before, the host .env
checksum stayed the same across a deploy, and the four keys holding host
paths resolve inside the container under the same paths.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:35:22 +02:00
kevinveenbirkenbachandClaude Opus 5.5 373d5c9dc7 fix(web-app-odoo): run the onion suite on full Chromium so its origin is secure
The shared Playwright config passes --unsafely-treat-insecure-origin-as-secure
for every .onion origin in the environment, but Playwright's default
chrome-headless-shell ignores that switch. On the tor axis the odoo origin
therefore stayed an insecure context: navigator.clipboard was undefined and
Odoo 20's onboarding tour crashed with "Cannot read properties of undefined
(reading 'writeText')" and "Cannot destructure property 'TourInteractive'",
opening error dialogs that the addon specs read as a missing module (odoo#2,
swarm tor, main run 38038541631).

When ODOO_BASE_URL is an onion URL the odoo specs now use channel "chromium",
the full Chromium build in the Playwright image, and block service workers;
clearnet runs keep every option unchanged. The worker is blocked because a
secure context lets Odoo register /web/service-worker.js, whose fetch handler
answers a failed navigation with a cached page or /odoo/offline: gotoOnion
would get a 200 instead of the transport error it retries on. The switch stays
in the role: a use.channel in the shared config would also reach the Firefox
launch of onion-test.js, which rejects it with "Unsupported firefox channel",
and would move every other role's onion run to a browser none of them was
tested on.

Verified with Playwright 1.63 in the runner's staging layout and the real
odoo specs: an onion ODOO_BASE_URL resolves channel "chromium" and
serviceWorkers "block", also for the contexts _shared.js creates itself, and
launches chromium-<rev>/chrome-linux64/chrome; a clearnet one, and HEAD's
specs on onion, keep the headless shell and "allow". All spec files stay on
one worker, which the suite's one-worker test requires. Against Odoo 20's
service worker with a dropped connection, full Chromium returned the cached
/odoo page with status 200, while with the worker blocked page.goto threw
net::ERR_CONNECTION_FAILED as the headless shell does. In the v1.64.0 image
full Chromium made no :443 attempt to an onion host and the onion origin
reported isSecureContext with crypto.subtle, which the headless shell did not.
A local deploy of web-app-odoo variant 2 over Tor ran the odoo suite on
/ms-playwright/chromium-1248/chrome-linux64/chrome and passed all seven addon
specs, the one-worker test and the guest flow without a retry; in the variant
0 round the suites of the other roles kept chrome-headless-shell.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:35:22 +02:00
kevinveenbirkenbachandClaude Opus 5.5 eda6249d7b fix(sys-svc-compose): probe provider networks by their exact name
The network probe used community.docker.docker_network_info, whose
get_network() scans GET /networks and returns the first entry whose Name
equals the requested name OR whose Id starts with it, in a list order that
changes between calls. In main run 38038541631 (Zammad#1, swarm) the
central redis overlay got the ID n8nwzb1q39m3u4k7awwwmt6yg, the probe for
the not yet created provider network "n8n" returned it as existing, the
create step was skipped, docker stack deploy attached hermes to the redis
overlay as "n8n", and the oauth2-proxy then reached the password-protected
central redis by its bare host name: "NOAUTH Authentication required".
The same scan can also return the ID-prefix twin of a network that does
exist, so comparing the returned name alone would turn that network into
"missing" and fail the create with "already exists".

Both probes now run `container network ls --filter name=<entity> --format
'{{json .}}'`, whose name filter never matches an ID. The new lookup
network_driver picks the entry named exactly after the entity and returns
its driver, '' when there is none; the drift checks, their messages and the
create steps all read that one entry. No docker module is left in the file,
so its two docker-module-uses-container-cli suppressions go too.

Verified: on the host daemon GET /networks/<id prefix> returns a network of
another name and docker network ls --filter name=<id prefix> returns
nothing. In ansible-playbook against real docker network ls output the
lookup returned the exact network's driver in 20 of 20 probes beside an
ID-prefix twin, an empty driver (create path) for a missing network and for
a name only contained in a sibling, and the drift path for a foreign
driver. Unit tests cover the same cases; with a substring match instead of
the exact name the two sibling cases fail.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:35:22 +02:00
kevinveenbirkenbachandClaude Opus 5.5 ba1e72a287 fix(sys-ctl-hlth-csp): pin csp-checker 3.0.5
csp-checker 3.0.5 starts Chromium without HTTPS-Upgrades. Before it, every
http:// onion vhost was first tried as https://host:443 through the Tor SOCKS
proxy, which broke the port-80 requests to the same onion service with
net::ERR_SOCKS_CONNECTION_FAILED. hlth-csp then failed all 25 start attempts
and took the deploy down in 11 swarm/tor jobs of main run 38038541631
(Gitea#0, Hugo#0, Listmonk#0, Mattermost#2, Nextcloud#0/#4/#7, Penpot#0,
Pixelfed#0, YOURLS#0, odoo#0).

Verified against a local compose stack over Tor: image 3.0.4 as shipped hit
the SOCKS error on css and asset and reported extra redirects elsewhere; with
the 3.0.5 change no SOCKS error and only the redirects the server sends. The
csp-checker lint and all 16 E2E tests pass on the image built from 3.0.5.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:35:22 +02:00
kevinveenbirkenbachandClaude Opus 5.5 ab9c23fa76 fix(web-app-suitecrm): run Symfony's session through the Redis handler too
3cefb01d71 moved PHP sessions to Redis by pointing session.save_path at
redis-central. SuiteCRM's own core_services.yaml wraps a
NativeFileSessionHandler around '%session.save_path%', and that handler
forces session.save_handler back to files and treats the Redis URL as a
directory ("is_dir(): Unable to find the wrapper "tcp""). Symfony's session
was empty on every request, so every POST /api/graphql answered 403
"Invalid CSRF token", the SPA logged the user out right after the SAML login
and the biber logout spec failed with "session was lost before the logout
attempt" (SuiteCRM#0 on PR #869, reproduced on main locally).

core_services.yaml is imported after every extension service file, so the
core handler cannot be redefined there. An extension packages file now
points framework.session at our own handler and storage factory, which wrap
PHP's built-in SessionHandler and therefore use phpredis from php.ini, with
its locking, for Symfony and the legacy app alike.

The entrypoint rebuilds the prod cache when an extension config is newer
than it, so an existing installation picks the wiring up instead of keeping
the compiled container.

Verified with a local compose deploy of variant 0: on main the SAML logout
spec failed with the 403 sequence above; after a mode=update redeploy the
cache was rebuilt, all three SAML specs passed, and the prod log shows no
tcp-wrapper warning or CSRF failure after the rebuild.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:35:22 +02:00
evangelostsak 34b49036d7 Merge remote-tracking branch 'upstream/main' into feature/svc-net-wireguard 2026-10-12 17:52:36 +02:00
kevinveenbirkenbach e320ef4e5d Merge pull request #894 from infinito-nexus/update/docker-image-versions-web-app-bigbluebutton-20261012-03b9279
update(images): update Docker image versions (web-app-bigbluebutton)
2026-10-12 09:45:57 +02:00
kevinveenbirkenbach 3fdfeeb076 Merge pull request #900 from infinito-nexus/update/version-sources-web-app-n8n-20261012-e274682
update(versions): update pins with a declared source (web-app-n8n)
2026-10-12 09:45:16 +02:00
infinito-nexus-updater[bot] 01f0ff139a update(versions): update pins with a declared source (web-app-n8n) 2026-10-12 07:42:16 +00:00
kevinveenbirkenbach cc66d490be Merge pull request #897 from infinito-nexus/update/version-sources-web-app-n8n-20261012-e274682
update(versions): update pins with a declared source (web-app-n8n)
2026-10-12 09:41:53 +02:00
kevinveenbirkenbach 0d2b18a52f Merge pull request #895 from infinito-nexus/update/docker-image-versions-web-app-gitlab-20261012-a89ac14
update(images): update Docker image versions (web-app-gitlab)
2026-10-12 09:41:23 +02:00
kevinveenbirkenbach 473b03a79f Merge pull request #899 from infinito-nexus/update/docker-image-versions-svc-ai-ollama-20261012-20f5f87
update(images): update Docker image versions (svc-ai-ollama)
2026-10-12 09:38:03 +02:00
kevinveenbirkenbach b5d8ad788f Merge pull request #898 from infinito-nexus/update/docker-image-versions-web-app-stalwart-20261012-be751bf
update(images): update Docker image versions (web-app-stalwart)
2026-10-12 09:37:37 +02:00
infinito-nexus-updater[bot] 8b887108ca update(images): update Docker image versions (svc-ai-ollama) 2026-10-12 07:37:10 +00:00
kevinveenbirkenbach 305ce1db7a Merge pull request #893 from infinito-nexus/update/docker-image-versions-svc-ai-ollama-20261012-20f5f87
update(images): update Docker image versions (svc-ai-ollama)
2026-10-12 09:37:06 +02:00
kevinveenbirkenbach 957420e799 Merge pull request #892 from infinito-nexus/dependabot/npm_and_yarn/playwright/test-1.64.0
chore(deps-dev): Bump @playwright/test from 1.63.0 to 1.64.0
2026-10-12 09:34:56 +02:00
infinito-nexus-updater[bot] c9befebc79 update(images): update Docker image versions (web-app-stalwart) 2026-10-12 07:34:18 +00:00
infinito-nexus-updater[bot] 2a37349a60 update(images): update Docker image versions (web-app-socialhome) 2026-10-12 07:34:13 +00:00
infinito-nexus-updater[bot] b2f77234ee update(versions): update pins with a declared source (web-app-n8n) 2026-10-12 07:34:12 +00:00
infinito-nexus-updater[bot] a9aec3305d update(images): update Docker image versions (web-app-gitlab) 2026-10-12 07:34:06 +00:00
infinito-nexus-updater[bot] 8637ba92d4 update(images): update Docker image versions (web-app-bigbluebutton) 2026-10-12 07:34:01 +00:00
infinito-nexus-updater[bot] cfaa9c61ac update(images): update Docker image versions (svc-ai-ollama) 2026-10-12 07:33:56 +00:00
kevinveenbirkenbach 4ceb89b330 Merge pull request #890 from infinito-nexus/update/docker-image-versions-web-app-socialhome-20261010-e5aebee
update(images): update Docker image versions (web-app-socialhome)
2026-10-12 09:33:22 +02:00
dependabot[bot] 9f263eef53 chore(deps-dev): Bump @playwright/test from 1.63.0 to 1.64.0
Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.63.0 to 1.64.0.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.63.0...v1.64.0)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.64.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-12 00:36:26 +00:00
Prageeth Panicker 44cff8669e Merge remote-tracking branch 'origin/main' into feature/web-app-wazuh/add-role 2026-10-11 14:14:01 +00:00
kevinveenbirkenbach 208dfa723f Merge remote-tracking branch 'origin/main' into HEAD 2026-10-10 10:38:29 +02:00
kevinveenbirkenbach 56bc07f363 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-10 10:38:20 +02:00
kevinveenbirkenbachandClaude Opus 5.5 38902309f4 fix(web-app-pixelfed): send the OIDC token exchange through Tor on an onion issuer
On an onion deployment Pixelfed's server-side code-to-token exchange dials
the Keycloak .onion authority. libcurl refuses to resolve .onion names
(RFC 7686) before /etc/hosts or the SSO extra_hosts pin is consulted, so the
callback died with "cURL error 6: Not resolving .onion address" and both
OIDC login specs timed out (Pixelfed#0, compose, Tor, PR #869 run
37954856725).

Pixelfed builds its league/oauth2 GenericProvider without a proxy option,
so the proxy has to come from the environment. When the issuer is an onion,
env.j2 now sets http_proxy and https_proxy to the Tor socks5h endpoint,
with the object store host in no_proxy. Both Pixelfed services pin
host.docker.internal, the compose SOCKS endpoint, since the worker reads
the same env file. Clearnet deploys render no proxy.

Verified with a local compose deploy of variant 0 (SSO, seaweedfs, Tor): the
rendered token URL is an .onion authority, the env carries
socks5h://host.docker.internal:9050, and both pixelfed OIDC login specs pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:37:42 +02:00
kevinveenbirkenbachandClaude Opus 5.5 1ba796d7f1 fix(ci): pull the images the runner uses itself from the GHCR mirror
The GHCR mirror covered role images only. The images the runner pulls on
its own went straight to Docker Hub: coredns from compose.yml, the cache
stack in compose/cache.override.yml and alpine:latest, the init image of
scripts/docker/cache/package-frontend/certs.sh. With the anonymous
githubactions quota spent, the guide step of Postmarks#0 (main run
37954203718) and Shopware#2 (#872) died on "toomanyrequests" while pulling
alpine:latest, after coredns had hit the same limit.

iter_runner_images (utils/docker/image/discovery.py) finds those images,
and the mirror sync and the fork-PR wait now cover them next to the role
images. On a real GitHub runner compose_file_args layers a generated
build/compose/runner-mirror.override.yml that points only the services of
the layered compose files at their mirror, and the certificate generator
gets the mirrored init image. Local runs and act are unchanged, and the
coredns literal stays in compose.yml for Dependabot. test-dns now waits for
images-mirror-missing like the deploy and workspace jobs, since it brings up
the stack too.

Verified with docker compose config on a simulated GitHub runner: the
service set is unchanged and only the runner images point at
ghcr.io/infinito-nexus/core/mirror/docker.io/..., and an existing role mirror
under that scheme pulls anonymously.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:37:41 +02:00
infinito-nexus-updater[bot] 274ba4ea5d update(images): update Docker image versions (web-app-socialhome) 2026-10-10 07:26:22 +00:00
evangelostsak 5faefee54b perf(swarm-test): take the sudo prompt off the lab administrator
Three runs of the transport benchmark, per module call:

              become off   become on
  docker          247ms       246ms
  ssh over mesh   215ms      1259ms

The connection is not the cost - ssh through the tunnel beats docker exec by
13% - and the tunnel is 4%. What the meshed arm pays is the sudo prompt: free
over the container connection, which runs as root, and 1046ms per escalated
call over ssh as the administrator. That is the 414ms per task the three-arm
comparison measured across a whole deploy.

A lab-only sudoers drop-in removes it. It is applied from the mesh prologue
while the inventory still reaches the nodes as root, so it is in place before
anything logs in as the administrator, and it touches no role: production
keeps 'administrator ALL=(ALL) ALL' and its password prompt.

The cost is that CI no longer exercises password sudo over the mesh. It never
exercised it on the direct arm either, which connects as root, and a wrong
password fails loudly rather than silently.
2026-10-09 23:33:11 +02:00
Prageeth Panicker 2a52e96c65 chore(web-app-wazuh): trigger CI for the review fixes 2026-10-09 19:18:17 +00:00
kevinveenbirkenbach 39018d1a07 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-09 17:50:46 +02:00
kevinveenbirkenbach e89b1e3b94 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-09 17:50:44 +02:00
kevinveenbirkenbachandClaude Opus 5.5 d43b86b022 fix(web-app-keycloak): read the account page body before the console redirects
The CSP spec opens /realms/<realm>/account/, the account console SPA, which
redirects to the login flow from JavaScript. The spec read response.text()
only after the header and meta CSP checks, and once the redirect had
committed Playwright 1.64 no longer holds the body. MediaWiki#0 (swarm) of
main run 37903645290 failed all three attempts at playwright.spec.js:116
with "Response body is not available for a response that was navigated
away from", while the same spec passed locally in under a second.

The body is now read right after the status check, as Playwright's own
message asks. The assertion on the canonical domain is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 17:46:12 +02:00
kevinveenbirkenbachandClaude Opus 5.5 eda3bdbc35 refactor(sys-svc-proxy): set the upstream request headers in one snippet
Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Port and
X-Forwarded-Ssl were written out separately in the html, ws and upload
locations and in the Prometheus health probes, and the copies had drifted:
ws and upload never sent Port and Ssl, and the probes sent only Host, which
is how the Shopware readiness probe came to see plain http.

headers/forwarded.conf.j2 now holds the set and every one of those locations
includes it. The html location renders the same headers as before. ws and
upload additionally send Port and Ssl with the values the html location
already gives the same backend. The ready and live probes gain X-Real-IP and
X-Forwarded-For, and the live probe the three X-Forwarded headers as well.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 17:15:22 +02:00
kevinveenbirkenbachandClaude Opus 5.5 66d5e60b57 fix(web-app-prometheus): forward the request scheme to the readiness probe backend
The /healthz/ready location proxied to the app with only the Host header.
An app that matches its configured domain including the scheme then sees a
plain http request. Shopware has no sales channel domain for
http://shop.infinito.test and answers 400, so blackbox reported
probe_success 0 and the scrape spec failed in Shopware#0 (swarm) of main run
37903645290: status_code=400 on every probe once Shopware was up, and
shopware_web logged GET / -> 400 for host shop.infinito.test.

The location now sends X-Forwarded-Proto, X-Forwarded-Port and
X-Forwarded-Ssl with the same values the html location gives every page
request to the same backend.

Verified on a local Shopware stack: /healthz/ready answers 200 with the
headers and 400 again once they are removed from the live vhost.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 17:15:21 +02:00
evangelostsak ca1a93f93a fix(swarm-test): give the benchmark its become password, and no veto
Run 37931817959 timed the four cells and two of them are real: a module
call costs 245ms over docker and 212ms over ssh through the tunnel, with or
without become on the docker side. The connection plugin is not the cost.

The escalated ssh cell is not real. The benchmark ran without the extras, so
ansible_become_password was absent and all 200 calls failed on 'Incorrect sudo
password' - 3.2s each, which prices a failing sudo rather than a working one.
It now passes the same two -e files the deploy passes.

Its exit code also reached the round, so a diagnostic turned three green
deploys red. transport_bench now discards its own rc: whether a deploy passes
is not a benchmark's business.
2026-10-09 16:19:46 +02:00
evangelostsak 64514b23a5 fix(swarm-test): name the bench playbook out of the playbook prefix
A second playbook-* file at the root makes 'playbook' a shared
delimiter-bounded prefix, and the structure lint reads that as a folder in
disguise: '2 files share the prefix playbook -> move them into ./playbook/'.
It failed test-lint, which gates the deploy chunks, so run 37929774651
produced no benchmark.

The alternative was renaming playbook-mesh.yml into a new playbook/ folder,
which is a structural change to the branch's own feature made for the sake of
a diagnostic. Renaming the diagnostic is the smaller move.

The local run missed it because the file was still untracked, and the rule
walks git ls-files.
2026-10-09 14:42:20 +02:00
evangelostsak 12f4dfe4a5 feat(swarm-test): price the transport against the escalation
The three-arm comparison on web-app-gitea#0 put the meshed arm at 414ms
per task over the direct arm, and the tunnel at 4% of that. What it could not
split is the rest: the arms differ both in connection plugin (docker against
ssh) and in escalation (root with no prompt against administrator with a
password sudo on every task).

A fixed set of module calls, timed either side of the transport switch with
become off and on, gives four numbers that separate the two. It costs about a
minute where a fourth deploy arm would have cost three hours, and it needs no
root login and no sudoers change.

INFINITO_SWARM_TRANSPORT_BENCH guards it, so a normal round times nothing.
2026-10-09 14:23:36 +02:00
evangelostsak ff1db88753 revert(swarm-test): remove the SSH-on-underlay measurement arm
The arm existed to answer one question: how much of the meshed arm's
cost is the connection plugin and how much is the tunnel. Runs 37592061960
(docker), 37753506661 (SSH on the underlay) and 37621556682 (SSH over
WireGuard) answered it on web-app-gitea#0, debian/ext4:

  pass 1  5964s / 8511s / 8832s
  pass 2  5319s / 7472s / 7705s

Leaving ansible_connection: docker costs +4700s, the tunnel +554s - 89.5%
against 10.5%. The answer is recorded; the scaffolding does not need to ship.

Reverts d792519725, 1b28f87b37, 89b8a8c8d1, 0470491e1a, 529c5ace43,
dd3d10a9a2, c20dd0e5f5, 458d8956e1, 63ade1e03b, d281555945 and 4adfb6e3d2.
95cfc8b7b7 is already superseded by bbfd82f89, which sets the profiling limit
upstream.
2026-10-09 12:12:03 +02:00
evangelostsak 5a83785b53 Merge remote-tracking branch 'origin/main' into feature/svc-net-wireguard 2026-10-09 12:00:07 +02:00
Prageeth Panicker f5b552a667 Merge remote-tracking branch 'origin/main' into feature/web-app-wazuh/add-role 2026-10-09 08:34:37 +00:00
Prageeth Panicker 70ea5bd691 refactor(web-app-wazuh): map the nofile limits over services.yml
The manager and indexer nofile limits now live next to their other resource settings in services.yml and the compose template reads them from there, as requested in review. The values are unchanged.
2026-10-09 08:18:07 +00:00
kevinveenbirkenbach ed988daaec Merge remote-tracking branch 'origin/main' into HEAD 2026-10-09 10:14:49 +02:00
kevinveenbirkenbach ea9755a344 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-09 10:14:44 +02:00