Commit Graph
342 Commits
Author SHA1 Message Date
evangelostsak 865b4cb7c2 docs(026): tick client-mode + NAT criteria (validated by nat.sh)
Client mode (MTU 1400) and the NAT masquerade rules are now covered by the nat.sh e2e stage. Documents how NAT is tested and that the host-level task stays container-gated. Awaiting fork-CI confirmation of nat.sh.
2026-07-09 13:47:46 +02:00
evangelostsak f86e693977 docs(026): tick CI-proven acceptance criteria and clarify NAT coverage
Server-mode deploy + the full DinD e2e (servers, handshakes, 6-node mesh) are now proven in the fork CI run. NAT and client mode remain unverified; documented why and how to test.
2026-07-09 13:47:46 +02:00
evangelostsak c6b20352dc refactor(svc-net-wireguard): move e2e harness to the test-e2e-cli contract
tests/ -> files/test/ (test.sh/local.sh/external.sh/mesh.sh) + templates/test.env.j2 (the test-e2e-cli discovery marker). README and requirement 026 updated to the adopted contract.
2026-07-09 13:47:45 +02:00
evangelostsak 91000d2243 docs(svc-net-wireguard): document automatic CI e2e-cli discovery 2026-07-09 13:47:45 +02:00
evangelostsak 389eceaa1a docs(requirements): add 026 svc-net-wireguard requirement 2026-07-09 13:47:45 +02:00
kevinveenbirkenbachandClaude Opus 4.8 945fbccc1e refactor(swarm): move service_replicas into services.yml
Replace the per-role service_replicas Jinja variable with a per-service
replicas: field in meta/services.yml. deploy.yml.j2 resolves it via
resource_filter (with entity fallback), the same path already used for
cpus/mem, so services.yml is the single source of truth for replica
overrides.

- 13 web roles migrated to per-service (or entity-level) replicas: 1
- matomo bootstrap -> replicas: 0, mastodon migrate -> replicas: 1
- minio/seaweedfs provider entries -> replicas: 1, which also pins the
  central single-writer object-store providers instead of relying on the
  topology default
- service_replicas removed entirely; dropped its dead reference from the
  compose-structure lint allowlist and updated requirement 023 wording

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 05:05:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e6538e4f61 feat(svc-net-tor): Tor onion-service provider (full onion node)
Turn a NAT/edge node into a full Tor v3 onion node: DOMAIN_PRIMARY
becomes the node's .onion, so the whole stack (web, SSO, LDAP, CA)
resolves onion domains and is reachable over Tor without a public IP,
port forwarding, VPS or DynDNS.

- utils/tor_onion.py: offline v3 key mint (address + HiddenServiceDir
  key files), verified against a known key->address test vector.
- cli .../inventory/onion: `init-env` pre-mints the node onion, writes
  INFINITO_DOMAIN(+_RE) into .env and authoritative key files into
  .onion-identity/hs (idempotent). The onion is a deploy-time input;
  no in-deploy random minting (that would not match the pre-set domain).
- roles/svc-net-tor: Tor sidecar (Debian-built, network_mode: host),
  installs the minted keys, torrc with one node HiddenService + a SOCKS
  proxy restricted to loopback/DiD ranges. files/test.sh probes every
  served onion domain over the Tor SOCKS.
- tls: .onion -> TLS off (onion v3 crypto is the transport auth; LE
  cannot sign .onion) + app-level flavor override.
- harness/DNS: coredns resolves the onion zone via INFINITO_DOMAIN;
  skip the clearnet DNS sanity check for onion; raise nginx
  server_names_hash_bucket_size to 128 for long onion server_names.
- test-e2e-playwright: gated browser SOCKS proxy (PLAYWRIGHT_PROXY) +
  navigation/action timeouts so specs reach .onion over Tor and fail
  fast; the onion node points it at the Tor SOCKS.
- docs/requirements/031: full design.

Verified: dashboard + SSO (Keycloak) + 9 apps reachable over Tor
(HTTP 200 through the node hidden service). make test green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 12:38:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 d549c2eaec docs(req): add 031 svc-net-tor full onion node requirements
Requirements for a Tor v3 onion-service provider role that turns a
NAT/CGNAT node into a full onion node: DOMAIN_PRIMARY becomes the node
.onion (whole stack shifts, no domain-transform), key minted offline at
inventory build, Tor sidecar restores it, per-domain TLS keeps optional
public domains, egress torification off by default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:42:52 +02:00
kevinveenbirkenbach 9ee4cd0fb9 Merge branch 'main' of github.com:infinito-nexus/core into feature/swarm-nfs
# Conflicts:
#	docs/agents/action/iteration/compose.md
#	roles/svc-db-openldap/vars/main.yml
#	roles/svc-runner/defaults/main.yml
#	roles/svc-runner/tasks/02_cleanup_instance.yml
#	roles/web-app-discourse/meta/server.yml
#	roles/web-app-mailu/tasks/01_core.yml
#	roles/web-app-odoo/tasks/main.yml
2026-07-04 18:16:12 +02:00
kevinveenbirkenbach 3b11c0b259 Merge pull request #358 from kevinveenbirkenbach/feature/web-app-checkmk
feat(web-app-checkmk): add Checkmk role with oauth2-proxy SSO + LDAP
2026-07-04 16:38:34 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4bb432db70 feat(web-app-jellyfin): add Jellyfin role with LDAP + OIDC SSO plugins
Implements requirement 030: web-app-jellyfin deploying jellyfin/jellyfin
10.11.11 behind sys-svc-proxy. No external DB (internal SQLite); /config,
/cache, /media named volumes; CPU transcoding. Jellyfin has no native SSO, so
auth is plugin-based (operator chose BOTH): jellyfin-plugin-ldapauth (central
OpenLDAP, all clients incl. native apps) + 9p4/jellyfin-plugin-sso (Keycloak
OIDC, web one-click). files/configure-auth.sh completes the first-run /Startup
wizard (seeds break-glass admin), installs both plugins via Jellyfin's own
/Packages installer, writes the plugin configs, and restarts.

Schemas source-verified against the pinned upstream: Jellyfin v10.11.11, LDAP
plugin v23 (GUID 958aad66-..., flat XmlSerializer config), SSO plugin v4.0.0.3
(OidConfig fields). Honest caveats: the SSO OidConfigs is a SerializableDictionary
(XML shape best-effort), plus plugin ABI compat + the SPA Playwright selectors
are live-deploy-validation items (env-blocked). Each config file is XML-well-
formedness checked before reload.

Validation: make autoformat clean; make test green (lint, test-lint, test-unit,
test-integration 190, test-external).

Refs: docs/requirements/030-web-app-jellyfin.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 11:35:36 +02:00
kevinveenbirkenbach 5ca10de67d Merge branch 'main' into feature/web-app-checkmk 2026-07-03 01:03:37 +02:00
kevinveenbirkenbach 506da992d7 Merge branch 'main' into feature/web-app-semaphore 2026-07-02 13:10:49 +02:00
kevinveenbirkenbach 9b2f870777 Merge branch 'main' into feature/swarm-nfs 2026-07-01 05:37:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c28ea68326 fix(web-app-semaphore): pin published image tag v2.18.12
v2.18.13 is not published on Docker Hub, so 'compose pull' failed with 'manifest unknown' and aborted the deploy. Pin v2.18.12 (latest stable 2.x, verified pullable in the nested daemon) and align the README bump-policy note and the 028 requirement spec.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:38:41 +02:00
kevinveenbirkenbachandClaude Opus 4.8 059232bd0d feat(web-app-checkmk): add Checkmk role with oauth2-proxy SSO + LDAP
Implements requirement 029: web-app-checkmk deploying checkmk/check-mk-raw
2.4.0p32 (Raw/Community) behind sys-svc-proxy. No native OIDC, so SSO uses the
platform oauth2-proxy gate + Checkmk header-auth (auth_by_http_header =
X-Remote-User, injected by the role proxy.conf.j2 from $authrequest_username =
Keycloak preferred_username), plus a native LDAP connection for user records.
No external DB. Agent receiver (8000) host-port mapped via a new
PORT_BANDS.local.agent band.

Auth/LDAP/proxy mechanisms source-verified against Checkmk v2.4.0p32
(cmk/gui/auth.py, userdb/ldap_connector.py, userdb/_connections.py) and the
infinito sso_proxy nginx chain: fixed the LDAP file path (user_connections.mk)
and directory_type ("openldap"). LDAP sync timing and classic-GUI Playwright
selectors remain live-deploy-validation items (env-blocked).

Validation: make autoformat clean; make test green (lint, test-lint, test-unit,
test-integration 190, test-external).

Refs: docs/requirements/029-web-app-checkmk.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 02:35:08 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6ce6780575 refactor(meta): split server.yml into csp/domains/networks.yml
Extract the csp, domains, and networks blocks out of roles/*/meta/server.yml
into dedicated meta files, each mapping to its own top-level applications key
via the recursive meta-walk:

  csp:      -> meta/csp.yml      -> applications.<app>.csp
  domains:  -> meta/domains.yml  -> applications.<app>.domains
  networks: -> meta/networks.yml -> applications.<app>.networks

Residual nginx/proxy keys (status_codes, client_max_body_size, locations,
ip6_enabled, config_upstream_url) stay in server.yml; an emptied server.yml is
deleted. 98 server.yml -> 249 new files, 74 deleted.

- Consumers repointed applications.<app>.server.{csp,domains,networks} ->
  applications.<app>.{csp,domains,networks} across templates, vars, tasks,
  lookups and filters.
- Infra readers migrated: canonical_domains_map, application_domain_index,
  build_ldap_role_entries, service-registry overlay discovery,
  roles_with_service, and the file-based readers utils/domains/list.py +
  utils/meta/scan.py (read the now-deleted server.yml directly).
- Detection + mapping: _META_TOPICS gains csp/domains/networks;
  ROLE_FILE_META_{CSP,DOMAINS,NETWORKS} constants + ROLE_FILES entries.
- New self-expiring lint guard (test_server_meta_no_split_fields) fails if a
  server.yml still carries a split field; auto-fails from 2026-12-28 as a
  delete reminder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:45:05 +02:00
kevinveenbirkenbachandClaude Opus 4.8 defa2d6db3 feat(web-app-semaphore): add Semaphore UI role with OIDC SSO + LDAP
Implements requirement 028: web-app-semaphore deploying semaphoreui/semaphore
v2.18.13 behind sys-svc-proxy with central PostgreSQL, native Keycloak OIDC
SSO, and LDAP login, plus guest/biber/administrator Playwright personas.

Auth/admin model verified against the upstream v2.18.13 source (config.go,
api/login.go, api/router.go, web/src/views/Auth.vue, config.schema.yaml,
cli/cmd/user_add.go): the OIDC callback matches by email and rejects local
users, the login form is LDAP-only when ldap_enable=true, and OIDC users are
never admin from a claim. The role therefore seeds a distinct break-glass
local admin and creates the Keycloak administrator as an external admin at
deploy time (semaphore user add --admin --external). Correct v2.x env names
(SEMAPHORE_LDAP_ENABLE/_SERVER/_BIND_DN/_BIND_PASSWORD/_SEARCH_DN, OIDC
provider JSON) confirmed against the source.

Validation: make autoformat clean; make test green (lint, test-lint,
test-unit, test-integration 190, test-external). Live full-matrix deploy +
Playwright still pending (host container runtime fault, environment-only).

Refs: docs/requirements/028-web-app-semaphore.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:40:26 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9539feb496 docs(requirements): add 028 web-app-semaphore role spec
Requirements for a web-app-semaphore role (Semaphore UI): native OIDC SSO via Keycloak, LDAP login, central PostgreSQL, single all-in-one container with embedded runner, always-on local-admin bootstrap plus OIDC claim->admin mapping, and Playwright persona coverage. Includes upstream research with cited sources and acceptance criteria.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 21:13:46 +02:00
Alejandro Roman 17d6ac904f Merge remote-tracking branch 'upstream/main' into feature/self-host-runners
# Conflicts:
#	.github/workflows/test-deploy-universal.yml
#	.github/workflows/test-deploy-workstation.yml
2026-06-27 23:45:38 +02:00
kevinveenbirkenbachandClaude Opus 4.8 36ebf34b64 Merge branch 'main' into feature/swarm-nfs
Resolve 69 conflicts across ~70 files: union main's image-version bumps and new service fields (bond, resource limits) with the swarm branch's default_placement / NFS / IS_STACK_HOST config; retire the three per-deploy-type test workflows main still edited (consolidated into compose+swarm); adopt main's run-once 01_core dispatchers while re-applying each role's swarm guard. Fix the post-merge lint surfaced by main's stricter rules: bond + resource-budget keys, container-exec stack-host gating + resolver routing, leaky/dead proxy vars, suitecrm once-flag, xwiki variant nocheck, nextcloud oversized-block to gated include, matrix-mdad capped at 3g. make autoformat clean, make test green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:13:55 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c76c6da6a8 feat(svc-storage-nfs-server): userspace nfs-ganesha flavor for the swarm-test + refactor agent iteration docs
svc-storage-nfs-server gains a backend flavor selected by services.nfs-server.flavor (default "{{ 'ganesha' if RUNTIME in ['dev','act'] else 'kernel' }}"). The ganesha flavor installs nfs-ganesha + FSAL_VFS and renders /etc/ganesha/ganesha.conf (NFSv4, Pseudo == Path so clients mount the real paths unchanged, Root_Squash on the export base and No_Root_Squash on the state subdir), reloaded via systemctl restart. It runs in the dev/act DinD swarm-test, where the host kernel nfsd is not network-namespaced and a privileged node driving exportfs would wedge it into a D-state. The kernel flavor keeps nfs-kernel-server + exportfs -ra for production and every non-dev/act runtime. 01_core dispatches on the flavor, 03_prepare holds the shared export preparation, flavor/{kernel,ganesha}/main.yml hold the per-backend install/render/service steps, and handlers gains the ganesha restart.

docs/agents/action/iteration: role.md renamed to compose.md (Compose Loop); new swarm.md for the swarm deploy loop split out of workflow.md; workflow.md trimmed to GitHub Actions workflow iteration; all cross-references updated; the duplicated README gotcha removed; the NFS gotcha rewritten to the ganesha design.

Also drops a retired-flag history comment in group_vars/all/01_modes.yml and a redundant comment in the init selection script, and allows WebFetch(repology.org) used during ganesha packaging research.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:30:34 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6122213ed2 feat(web-app-matrix): migrate dead mautrix-facebook/instagram to mautrix-meta + gate bridge specs by deployed addon
Legacy mautrix-python facebook/instagram bridges are EOL and fail at runtime (appservice bot masquerade 403). Replace both with the bridgev2 mautrix-meta addon: config, schema credential, variant-2 wiring, and a profile spec with a positive @metabot probe plus an un-bridged-MXID negative control.

playwright.env.j2 now emits MAUTRIX_<bridge>_ADDON_ENABLED only for bridges that are actually deployed, so each bridge spec runs iff its bridge is up (closes the skip-as-green gap) and is telegram-drop aware.

Verified: compose variant-2 deploy failed=0; @metabot registers on the live Synapse; bridge suite green (meta/signal/whatsapp/slack), telegram skips (no API creds).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:45:58 +02:00
Alejandro Roman 0153b5cac1 fix CI failures after rebase 2026-06-24 18:30:58 +02:00
Alejandro Roman 764a1adf30 feat(svc-runners): add the logic to have x numbers of runners self hosted ad connected to GIthub, allowing to have 20 runners from gh + x self hosted 2026-06-24 18:30:31 +02:00
kevinveenbirkenbach 21e484bf30 Merge origin/main into feature/026-unified-addon-syntax
Resolve conflicts: keep 026's bond/field/addon additions (services.yml, variants.yml,
yourls leaky-proxy fix, nextcloud per-file addons), take main's 027 integration-matrix
(generated artifact). Verified: all 44 main inline-plugins are covered by meta/addons/.
2026-06-21 06:32:17 +02:00
kevinveenbirkenbachandClaude Opus 4.8 5cd9053b05 docs(requirements): add 028 atmo.rsvp role + Mobilizon bridge
File requirement 028 for a self-hosted web-app-atmo role (upstream
flo-bit/atmo-events) that reuses web-app-bluesky for AT Protocol
identity, plus a one-way AT Protocol -> ActivityPub event bridge to
web-app-mobilizon. Index it in the requirements README and allow
WebFetch(atmo.rsvp), used while researching the upstream project.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 23:35:25 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cdb7c49f69 docs(addons): document req-026 syntax; exclude desk-* roles from per-addon spec rule
Document the unified addon syntax (req-026) and drop the non-existent '# nocheck: playwright-addon-spec' escape hatch so the docs match the no-exemption lint. Exclude desktop desk-* roles from the per-addon Playwright spec requirement — they drive no web surface a spec could exercise — and harden the lint to FORBID spec files under desk-* roles; remove the 8 desk-chromium/desk-firefox/desk-gnome addon specs accordingly. Web-facing roles still require a spec per addon with no exemption.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:16:55 +02:00
kevinveenbirkenbachandClaude Opus 4.8 51c3d41ede Merge origin/main into feature/swarm-nfs
Reconcile main's object-store feature and pre-swarm deploy tasks with the branch's compose/networks/volumes SPOT and swarm lints.

objstore (seaweedfs/minio): standalone compose + embedded service templates migrated to the container_image/container_volumes/container_networks/compose_volumes/compose_networks/depends_on lookups; meta/volumes.yml on the canonical dict schema with s3.json and nginx.conf as type:config; embedded services made swarm-compatible via compose_only/compose_restart.

deploy tasks (erpnext, opentalk, seaweedfs, shopware, snipe-it, wordpress, yourls): container exec routed through the container_address resolver and gated on IS_STACK_HOST, shell module plus stack_host_template, no chdir or compose-verb forms.

Also removed orphaned vars, restored MAILU_INSTANCE_DIR, freed the seaweedfs subnet (192.168.206.0/24), stripped literal quotes from the nextcloud/bookwyrm env templates, and routed main's objstore compose_volumes tests through dir_var_lib.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:08:49 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9f65b558dc docs(026): unified addon syntax spec + acceptance check-off
Per-file meta/addons/<id>.yml convention throughout; 18 end-to-end-verified acceptance criteria checked off, 37 held (matrix-wiring backlog, audit/update automation, deploy-gated per-role).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 11:30:47 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4e807e64c2 docs(027): regenerate integration matrix from data module (req 026)
Split the generator data into integration_matrix_data.py and regenerate 027-integration-matrix.md (82x82, 523 wired + 96 upstream edges). Artifact is generated, not hand-edited.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 11:30:47 +02:00
kevinveenbirkenbach 920268fe42 fix(ci): pin variant[2] seaweedfs in matrix/shopware/snipe-it/taiga and nocheck flaky baserow URL 2026-06-17 11:30:38 +02:00
kevinveenbirkenbach 0310629287 fix(integration-matrix): clear generator lints and replace 2 dead edge URLs 2026-06-17 11:30:38 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e8c1657c37 docs(requirements): fold resolved decisions into unified-addon-syntax + renumber 028->026
Renumber the addon-syntax requirement 028 -> 026 (trio: 025-mcp -> 026-unified-addon
-> 027-integration-matrix) and bake in the agreed decisions:

- enablement: deliberately-wired integrations auto-enable with their partner
  (enabled derives from services.<target>.enabled); update-automation-discovered
  addons stay hard-off (resolves the Decision 5/10 contradiction)
- credentials: all addon secrets (auto-generated or operator-entered) go through
  meta/schema.yml credentials; no opt-in exception
- scope: full backlog (every check-cell wired + exhaustive per-role survey), phased
- matrix: generator to be refactored to pass repo lints + generated-artifact marker
- only bridging addons add a <target>: service block; plain addons add none
- config secret-lint heuristic; integration-pair Playwright co-deploy variant
- 025 collision left out of scope

Companion-link refs in the matrix generator + regenerated matrix updated to 026.
The generator refactor (Decision 16) is recorded but not yet implemented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:37 +02:00
kevinveenbirkenbachandClaude Opus 4.8 0e0dad26d6 docs(requirements): emit markdownlint-clean Notes block in the matrix generator
Add the blank line after `Notes:` (markdownlint MD032) in the generator HEADER so
a fresh `027-integration-matrix.gen.py` run stays lint-clean and idempotent with
autoformat. Regenerate the matrix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:37 +02:00
kevinveenbirkenbachandClaude Opus 4.8 45188939bb chore(requirements): mark integration-matrix generator executable (ruff EXE001)
The generator carries a `#\!/usr/bin/env python3` shebang; make the file
executable so ruff's flake8-executable check passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:37 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2281535162 docs(requirements): renumber MCP matrix + addon-syntax (026 -> 027/028) after merge
feature/mcp's 026-integration-matrix and 026-unified-addon-syntax collided with
main's numbering on merge. Renumber both and fix every cross-reference:
- 026-integration-matrix.{md,gen.py} -> 027-integration-matrix.{md,gen.py}
- 026-unified-addon-syntax.md        -> 028-unified-addon-syntax.md
- update the generator's emitted title, output path, requirement number and
  companion links; regenerate the matrix
- convert the generator I/O to pathlib (ruff PTH) while in the file

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:37 +02:00
kevinveenbirkenbach a58e7e53a2 Merge branch 'feature/mcp' into fix/ci-deploy-server-failures
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2026-06-17 11:30:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8a34d47165 docs(requirements): add 026 cross-role integration matrix
Add the generated role×role integration matrix (026-integration-matrix.md
+ generator) and expand 026 with: required-gated install-failure handling,
mechanism=bridge for network bridges, addon variant/matrix axis, and the
matrix-backed cross-role integration backlog. The matrix scans every role's
meta/services.yml for infinito-native wired edges (☑️) and overlays curated,
web-verified upstream plugin edges (✅/🪙): 511 wired + 96 upstream across 82
roles. Header repeats every 10 rows and columns for readability.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:30 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9a8a84cde8 docs(requirements): add 026 unified addon syntax
Promote per-app addon/plugin/extension/module/bridge declarations to a
single file-rooted meta/addons.yml contract: unified schema, explicit
cross-role bridge rule, required-gated install-failure handling (hard
fail vs warn+skip), addon state as a variants.yml matrix axis, network
bridges (Matrix mautrix) as mechanism=bridge addons, external drift
monitoring, and a Playwright test per user-facing addon. Audit expanded
to matrix, discourse, pretix, mattermost, desk-chromium/firefox/gnome;
mobilizon/bookwyrm DB extensions classified out of scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:30 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e6570e1486 docs(requirements): add 025 MCP role integration
Define the unified MCP service, identity, proxy, and test contract for
server and client roles, with a repo-wide audit, bridge discovery via
roles_with_service, and a Playwright test per integrated role.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:30:30 +02:00
kevinveenbirkenbach 29519603ef Merge remote-tracking branch 'origin/main' into feature/swarm-nfs 2026-06-14 20:32:59 +02:00
kevinveenbirkenbach f29ed13b3d fix(ci): pin variant[2] seaweedfs in matrix/shopware/snipe-it/taiga and nocheck flaky baserow URL 2026-06-13 19:55:03 +02:00
kevinveenbirkenbach c1be4241aa fix(integration-matrix): clear generator lints and replace 2 dead edge URLs 2026-06-13 18:20:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6ee047caa6 docs(requirements): fold resolved decisions into unified-addon-syntax + renumber 028->026
Renumber the addon-syntax requirement 028 -> 026 (trio: 025-mcp -> 026-unified-addon
-> 027-integration-matrix) and bake in the agreed decisions:

- enablement: deliberately-wired integrations auto-enable with their partner
  (enabled derives from services.<target>.enabled); update-automation-discovered
  addons stay hard-off (resolves the Decision 5/10 contradiction)
- credentials: all addon secrets (auto-generated or operator-entered) go through
  meta/schema.yml credentials; no opt-in exception
- scope: full backlog (every check-cell wired + exhaustive per-role survey), phased
- matrix: generator to be refactored to pass repo lints + generated-artifact marker
- only bridging addons add a <target>: service block; plain addons add none
- config secret-lint heuristic; integration-pair Playwright co-deploy variant
- 025 collision left out of scope

Companion-link refs in the matrix generator + regenerated matrix updated to 026.
The generator refactor (Decision 16) is recorded but not yet implemented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 16:59:05 +02:00
kevinveenbirkenbachandClaude Opus 4.8 0837630ac9 docs(requirements): emit markdownlint-clean Notes block in the matrix generator
Add the blank line after `Notes:` (markdownlint MD032) in the generator HEADER so
a fresh `027-integration-matrix.gen.py` run stays lint-clean and idempotent with
autoformat. Regenerate the matrix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:53:08 +02:00
kevinveenbirkenbachandClaude Opus 4.8 a0a0eac61e chore(requirements): mark integration-matrix generator executable (ruff EXE001)
The generator carries a `#\!/usr/bin/env python3` shebang; make the file
executable so ruff's flake8-executable check passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:53:08 +02:00
kevinveenbirkenbachandClaude Opus 4.8 48f8000c6e docs(requirements): renumber MCP matrix + addon-syntax (026 -> 027/028) after merge
feature/mcp's 026-integration-matrix and 026-unified-addon-syntax collided with
main's numbering on merge. Renumber both and fix every cross-reference:
- 026-integration-matrix.{md,gen.py} -> 027-integration-matrix.{md,gen.py}
- 026-unified-addon-syntax.md        -> 028-unified-addon-syntax.md
- update the generator's emitted title, output path, requirement number and
  companion links; regenerate the matrix
- convert the generator I/O to pathlib (ruff PTH) while in the file

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:53:07 +02:00
kevinveenbirkenbach 6332071668 Merge branch 'feature/mcp' into fix/ci-deploy-server-failures
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2026-06-13 15:29:56 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6c38fcf5c8 docs(requirements): add 026 cross-role integration matrix
Add the generated role×role integration matrix (026-integration-matrix.md
+ generator) and expand 026 with: required-gated install-failure handling,
mechanism=bridge for network bridges, addon variant/matrix axis, and the
matrix-backed cross-role integration backlog. The matrix scans every role's
meta/services.yml for infinito-native wired edges (☑️) and overlays curated,
web-verified upstream plugin edges (✅/🪙): 511 wired + 96 upstream across 82
roles. Header repeats every 10 rows and columns for readability.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:29:54 +02:00