Commit Graph
8 Commits
Author SHA1 Message Date
jschoubben 1f0c3ac69e fix: db/cache/store providers must serve their port; drop baserow's empty redis contribution
The breadth install (catalogue-broad) surfaced two latent resolution bugs that
single-module compile checks never caught (compile != resolve):

1. postgres/redis/mongodb/minio served no "port", yet seven consumers
   (baserow, letta, invoicing, gitea, umami, keycloak, nextcloud) reference
   ${bound:<provision>:port}. A binding auto-carries at/from/as; the port is the
   provider's half of the answer and must be declared in `serves` (manifest.go:
   "Serves is what a consumer needs to know ... a port, a path, a realm"). Added
   port to each: postgres 5432, redis 6379, mongodb 27017, minio 9000. Without it
   no DB consumer could resolve, let alone deploy.

2. baserow declared an empty contribution `contributes: {"redis-cache": {}}`.
   redis's serves spec for the cache is empty (a cache takes no per-consumer
   payload), so a consumer only `requires` it; an empty contribution is refused.
   Dropped it (requires/binds/secrets unchanged).

Found by mesh-lab catalogue-broad; the same fixes are mirrored in that bed.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-06 02:38:22 +02:00
jschoubben 6e8c18afff Resync hq ADR references 0044-0054 -> 0039-0049 after the hq record reconciliation 2026-09-05 12:49:16 +02:00
jschoubben 08bdd0e456 Providers: broker-bound runtime container replaces the old provisioner (ADR 0052/0053)
Each provider's separate provisioner container becomes a runtime container that
serves the module's tools and runs its provisioner under the module's scoped broker
account: mesh-runtime-<module>, on the backend's own network (reaching the backend
by name and the broker by NAT), with MESH_BROKER_FILE + MESH_RECEIVES replacing
GRANTS. umami gains the broker own-secret it lacked. cloudflare-dns's adapter is
re-pointed at the ADR 0053 contract (a data provision, like umami — its record
return is the scoped-out concern).

Proven: provider-on-backend-network green — redis's runtime, on the private redis
network, binds the broker and provisions a consumer with the mesh's credential.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-05 00:52:09 +02:00
jschoubben 3b03fcd8f7 Providers create the credential the mesh minted, sealing nothing (ADR 0053)
redis, postgres and minio adapters drop generatePassword + the returned credential:
each creates the resource under the login the mesh derived (`as`) with the password
the mesh minted (`p.password`). minio's client gains a secret-key argument so it sets
the mesh's secret rather than generating one. umami (analytics) is re-pointed at the
new contract too; its siteId return is a data-provision concern ADR 0053 scopes out.

Proven: mesh-lab provider-uses-mesh-credential green — redis creates the consumer's
login with the mesh's password, the consumer authenticates (PONG), no seal key set.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-05 00:27:37 +02:00
jschoubben 67d8d0dcbd catalogue: one mesh-state namespace — /var/lib/mesh/<module>/ (consistency)
The review found broker own-secret paths drifting: mostly /var/lib/<module>/
broker, but grafana/redis/icecast/nextcloud carried a '-module' suffix to dodge
a collision with the service's own /var/lib/<name> data, and photos sat under
/etc. Normalized to one collision-free namespace a service never owns:
/var/lib/mesh/<module>/broker, with a mesh-state directory resource for the
parent, across 24 modules. audit-logger is grandfathered (lab-proven, referenced
by the assigned test, and it has no service to collide with). All 33 manifests
parse; no client hardcoded a path, so nothing in code moved.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-04 21:28:55 +02:00
jschoubben 5fd78a77ad minio: provisioner emits best-effort, so a missing broker can't fail provisioning
The review found minio's provisioner emitting with a bare await, which throws
when no broker is bound (a provisioner is not yet a runtime — ADR 0052) and so
fails create/remove. Wrapped like the other providers: the event is logged and
dropped, the bucket still made. The real fix — the provisioner carrying a broker
credential — is ADR 0052.
2026-09-04 21:25:42 +02:00
jschoubben f689b7dfa6 minio: full nox module — client, tools, provisioner and events (ADR 0044/0045/0046)
Object store, an s3-bucket provider. Client ported with no npm deps: S3 data
plane over fetch + SigV4 (node:crypto), scoped access keys via the mc CLI (the
admin API needs an Argon2 payload node built-ins can't make — the honest port
hal also used). Tools: list buckets/objects, bucket info, presigned url. The
provisioner makes a bucket + scoped key per grant and emits
module.minio.bucket.created/removed (the secret stays off the bus). Typechecks;
manifest parses.

(Trimmed the generated self-consuming ledger: a provider need not subscribe to
its own emits.)
2026-09-04 02:35:51 +02:00
jschoubben c5efbd53ca A module is a package, not a bare manifest
Each module becomes modules/<name>/ holding module.json, with room for
the rest of what a module is — its tools, health checks, provisioning,
lifecycle — which the conversion from hal still has to bring across.
The flat <name>.json was only the resource-declaration half.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-03 00:47:14 +02:00