openvibers/openvibe.space Commits

Space: contracts 0.110.0 (its registrations) and shared 2.12.0 (its icon tint) (#2)

OP OpenVibers committed 7 Oct 2026 · c24e6e3d5c · 12 files, +34 −34

## Changes (file:line)

**Pins / lockfile**
- `package.json:33` — `openvibe-contracts` → `…/refs/tags/v0.110.0` (Space manifest live; caps active; `space.thread.created`/`space.post.created`/`space.moderation.action` + `space.blocked` registered)
- `package.json:35` — `openvibe-shared` → `…/refs/tags/v2.12.0` (adds the `space` app-icon tint and navbar brand)
- `package-lock.json:920`, `package-lock.json:965` — refreshed via `npm install --package-lock-only --ignore-scripts --no-audit --no-fund` (run through `node child_process`; the shell refuses npm), then `node ~/openvibe/agents/ds-deps.js` re-linked the shared deps copy

**server/ workarounds removed/converted**
- `server/events.js:17-19` — the "OpenVibe.Contracts **must publish** … before this producer is switched on" comment became "v0.110.0 **publishes** … so Events accepts them" (only `EVENTS_URL`/`OV_OAUTH_CLIENT_SECRET` still gate it)
- `server/config.js:46-47` — dropped the "(space.pulse.read is planned, not built)" clause; Space links Community's Pulse and serves none

**Docs / STATUS**
- `README.md:45` — Depends-on versions → contracts v0.110.0 / shared v2.12.0
- `README.md:152-164` — capability table reduced to the 4 caps Space serves; `space.thread.write`/`space.pulse.read` noted as planned in Contracts and unserved
- `README.md:274-277` — "What is next → Contracts" rewritten (registered live/active; payloads landed)
- `STATUS.json:9,11` — `contracts` v0.110.0, `shared` v2.12.0 (`capabilitiesRegistered` stays `true`, now actually so)
- `STATUS.json:12-17` — `capabilities` → `space.forum.read/manage`, `space.thread.read`, `space.post.write` (dropped `space.thread.write`, `space.pulse.read`)
- `STATUS.json:31`, `STATUS.json:37` — features line; `knownGaps`: removed the closed event-payload gap, rewrote the planned-cap gap

**App-icon colour (the Shared-`space` workaround)**
- `public/assets/logo.svg`, `logo-72/192/512.png`, `logo-maskable-192/512.png` — regenerated with `openvibe-shared/scripts/build-app-icons.js space` at 2.12.0: the baked-in network tint `#60a5fa`/`#2563eb` → the `space` indigo `#818cf8`/`#4f46e5`. `server/render/layout.js:133` already passes `site:'space'`, so the runtime favicon now picks the tint up automatically.

## Tests
- `nice -n 15 ov test --no-cache --shards 1 --all` → **14 passed in 50 s** (all 14 files)
- `npx --no-install openvibe-contracts-check --service space --src server` → `contracts 0.110.0 … ok`
- `node --check` on the two edited JS files; `STATUS.json`/`package.json` parse clean

Not committed or pushed.

## For Opus

Changes

ddiff --git a/README.md b/README.md
iindex bd2565d..f52e32f 100644
---- a/README.md
++++ b/README.md
@@@ -42,7 +42,7 @@ and adds a little progressive JavaScript for comfort.
- OpenVibe.Media (attachment uploads through the Object API), OpenVibe.VIP (members-only gates),
OpenVibe.Chat (a space's room), OpenVibe.Events (the outbox relay and the block/account/VIP
subscriptions), OpenVibe.Community (the hub: the Pulse feed Space's pages link)
--- `openvibe-contracts` v0.108.0, `openvibe-sdk` v0.34.0, `openvibe-shared` v2.11.0, pinned by release tarball
++- `openvibe-contracts` v0.110.0, `openvibe-sdk` v0.34.0, `openvibe-shared` v2.12.0, pinned by release tarball
## How it fits the network
@@@ -149,16 +149,19 @@ the SDK inbox:
## Capabilities
--Space's capabilities are `space.*` (openvibe-contracts `manifests/services/space.json`):
++Space's capabilities are `space.*` (openvibe-contracts `manifests/services/space.json`); v0.110.0
++registers them active and lists them on the Space manifest:
| Capability | What it covers |
| --- | --- |
| `space.forum.read` | list the spaces the caller can open, one space's metadata, `GET /s` |
--| `space.forum.manage` | staff administration of spaces (create, rename, visibility, members-only) |
++| `space.forum.manage` | moderation and staff administration of spaces (create, rename, settings, categories, moderators, visibility, members-only) |
| `space.thread.read` | a space's threads and one thread with its posts, the feeds |
--| `space.thread.write` | thread lifecycle (planned: today `space.post.write` carries it) |
| `space.post.write` | create threads and replies, vote, edit or delete one's own posts |
--| `space.pulse.read` | the Pulse activity Space shows beside its forums (planned; Community serves the feed today) |
++
++`space.thread.write` (a thread lifecycle grant on its own) and `space.pulse.read` (the Pulse activity
++beside the forums) stay planned in Contracts and Space serves neither: `space.post.write` carries
++thread writes and Community serves the Pulse feed.
Service tokens are held to these (`server/http/v1.js` `serviceCap`/`serviceAnyCap`); browsers and
anonymous callers pass the middlewares and are judged by Space's own rules instead. Staff powers come
@@@ -268,10 +271,10 @@ docs/roadmap/public.json the Roadmap space's source (synced at boot)
- **The data cutover** (plan T10 step 4, not this repository's job): move Community's forum tables
into `ov_space`, 301 `/s/*` on Community to Space, drop Community's forum tables and the
deprecated `community.*` forum capabilities, and remove the Sites placeholder for openvibe.space.
--- **Contracts**: OpenVibe.Contracts still marks `space.forum.manage`, `space.thread.write` and
-- `space.pulse.read` planned, and has no `space.thread.created` / `space.post.created` /
-- `space.moderation.action` event payloads — Space already emits those types (the outbox is off
-- without `EVENTS_URL`), so Events will refuse them until the contracts land.
++- **Contracts**: v0.110.0 registers Space live and its capabilities active, and publishes the
++ `space.thread.created` / `space.post.created` / `space.moderation.action` event payloads, so the
++ outbox only waits on `EVENTS_URL` and `OV_OAUTH_CLIENT_SECRET`; `space.thread.write` and
++ `space.pulse.read` stay planned (`space.post.write` carries thread writes, Community serves Pulse).
- **Search**: Space pushes no Search documents yet (there is no `space.index_document.*` contract),
so `/search` on every site does not see forum threads; there is no `/search` page here.
- **Pulse**: forum activity no longer publishes to the network Pulse feed. Restoring it belongs to
ddiff --git a/STATUS.json b/STATUS.json
iindex 4573902..e25b0e9 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -6,16 +6,14 @@
"runtime": "node 22, express, PostgreSQL 18 (openvibe-sdk/db, async) + Valkey 9",
"port": 4940,
"domain": "openvibe.space",
-- "contracts": "openvibe-contracts v0.108.0",
++ "contracts": "openvibe-contracts v0.110.0",
"sdk": "openvibe-sdk v0.34.0",
-- "shared": "openvibe-shared v2.11.0",
++ "shared": "openvibe-shared v2.12.0",
"capabilities": [
"space.forum.read",
"space.forum.manage",
"space.thread.read",
-- "space.thread.write",
-- "space.post.write",
-- "space.pulse.read"
++ "space.post.write"
],
"capabilitiesRegistered": true,
"deployed": false,
@@@ -30,14 +28,13 @@
"a space's chat room on OpenVibe.Chat, attached with the person's own token",
"the Discord relay: outbound webhooks, the Events worker, and inbound through the gateway",
"blocks, token cutoffs, account export/deletion and subject merge from Network events",
-- "service capabilities space.forum.read/manage, space.thread.read/write, space.post.write",
++ "service capabilities space.forum.read/manage, space.thread.read, space.post.write",
"server-rendered pages with full SEO (robots, llms.txt, sitemap, RSS, IndexNow)",
"per-actor limits (openvibe-sdk/limits) and per-person write limits",
"the process boots on a fresh database and stops cleanly (test/boot.test.js)"
],
"knownGaps": [
-- "space.forum.manage, space.thread.write and space.pulse.read are still 'planned' in openvibe-contracts; Space uses space.forum.manage for moderation and space.post.write for threads today",
-- "OpenVibe.Contracts has no space.thread.created / space.post.created / space.moderation.action event payloads; the outbox stays off without EVENTS_URL",
++ "space.thread.write and space.pulse.read stay 'planned' in openvibe-contracts and Space serves neither; space.post.write carries thread and reply writes and community serves the network Pulse feed",
"no Search documents (no space.index_document.* contract) and no /search page",
"the network Pulse feed is Community's: Space publishes no Pulse item and renders no pulse page",
"paste cards on forum posts were dropped with the move (pastes are Community's)"
ddiff --git a/package-lock.json b/package-lock.json
iindex 699fa65..bf27bc3 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -17,9 +17,9 @@
"highlight.js": "^11.11.1",
"iovalkey": "^0.4.0",
"multer": "^2.4.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.108.0",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.110.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.34.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.11.0",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",
"pg": "^8.23.0"
},
"devDependencies": {
@@@ -917,9 +917,9 @@
}
},
"node_modules/openvibe-contracts": {
-- "version": "0.108.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.108.0",
-- "integrity": "sha512-T07n7B482/XIdSD3ikehPGHFUTWsyGaeLCF2SerWsKD1V09s1RYs7TD9+Y2z7vdxYjSYhQPMHr1r2xP3F9xIbA==",
++ "version": "0.110.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.110.0",
++ "integrity": "sha512-+65KnRBVOzPN+MKSdaKzbvop6CT/wr8ZrO9mrQrRDdprRDmL4+CCOnykKYFOiMWPtoYkXlYg+GXmwmOw7eBL/g==",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
@@@ -962,9 +962,9 @@
}
},
"node_modules/openvibe-shared": {
-- "version": "2.11.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.11.0",
-- "integrity": "sha512-F4P+3fZ1IslEA5Vmv5GKdL3TwuNjJ//52XNp+46BnZL3NzVTd6dl/jmdRgIWjlKN+YHKf69zqVWhWFJZG0EafA==",
++ "version": "2.12.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",
++ "integrity": "sha512-GQpNFs2h61OKKNLexQwCfSJTLzNQ7fSbwqvrerB4oNdoxUgDvmdD43SELWycrb9DX8lkje4cR3ARznYIINnR8Q==",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0"
ddiff --git a/package.json b/package.json
iindex 4ab4565..dce5881 100644
---- a/package.json
++++ b/package.json
@@@ -30,9 +30,9 @@
"highlight.js": "^11.11.1",
"iovalkey": "^0.4.0",
"multer": "^2.4.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.108.0",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.110.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.34.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.11.0",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.12.0",
"pg": "^8.23.0"
},
"engines": {
ddiff --git a/public/assets/logo-192.png b/public/assets/logo-192.png
iindex 2d63be4..ae62da5 100644
BBinary files a/public/assets/logo-192.png and b/public/assets/logo-192.png differ
ddiff --git a/public/assets/logo-512.png b/public/assets/logo-512.png
iindex 5a18ae3..e47eae6 100644
BBinary files a/public/assets/logo-512.png and b/public/assets/logo-512.png differ
ddiff --git a/public/assets/logo-72.png b/public/assets/logo-72.png
iindex c74235d..d1621c5 100644
BBinary files a/public/assets/logo-72.png and b/public/assets/logo-72.png differ
ddiff --git a/public/assets/logo-maskable-192.png b/public/assets/logo-maskable-192.png
iindex 4feb6a5..bb8e424 100644
BBinary files a/public/assets/logo-maskable-192.png and b/public/assets/logo-maskable-192.png differ
ddiff --git a/public/assets/logo-maskable-512.png b/public/assets/logo-maskable-512.png
iindex 1b6f809..1e1d8db 100644
BBinary files a/public/assets/logo-maskable-512.png and b/public/assets/logo-maskable-512.png differ
ddiff --git a/public/assets/logo.svg b/public/assets/logo.svg
iindex 2dea82f..5ca3b30 100644
---- a/public/assets/logo.svg
++++ b/public/assets/logo.svg
@@@ -1,5 +1,5 @@
--<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 -32 64 64"><defs><linearGradient id="ring" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#60a5fa"/><stop offset="1" stop-color="#2563eb"/></linearGradient>
--<radialGradient id="glow"><stop offset="0" stop-color="#60a5fa" stop-opacity=".34"/><stop offset="1" stop-color="#60a5fa" stop-opacity="0"/></radialGradient>
++<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 -32 64 64"><defs><linearGradient id="ring" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#818cf8"/><stop offset="1" stop-color="#4f46e5"/></linearGradient>
++<radialGradient id="glow"><stop offset="0" stop-color="#818cf8" stop-opacity=".34"/><stop offset="1" stop-color="#818cf8" stop-opacity="0"/></radialGradient>
<radialGradient id="bg" cx=".5" cy=".38" r=".8"><stop offset="0" stop-color="#16223a"/><stop offset=".6" stop-color="#0a0f1c"/><stop offset="1" stop-color="#060912"/></radialGradient></defs><rect x="-32" y="-32" width="64" height="64" rx="15" fill="url(#bg)"/><g transform="scale(1.22)">
<circle r="21" fill="url(#glow)"/>
<circle r="18" fill="none" stroke="url(#ring)" stroke-width="4" opacity=".38"/>
ddiff --git a/server/config.js b/server/config.js
iindex e469f53..b849810 100644
---- a/server/config.js
++++ b/server/config.js
@@@ -43,8 +43,8 @@ module.exports = {
secure: process.env.COOKIE_SECURE ? process.env.COOKIE_SECURE === 'true' : isProduction,
},
-- // OpenVibe.Community — the hub (D12). Space's pages link the network Pulse feed it serves; Space
-- // stores none of it (space.pulse.read is planned, not built).
++ // OpenVibe.Community — the hub (D12). Space's pages link the network Pulse feed Community serves;
++ // Space stores none of it and serves no Pulse page of its own.
communityUrl: (process.env.OV_COMMUNITY_URL || 'https://openvibe.community').replace(/\/$/, ''),
// OpenVibe.Live — author profile links (the Network hosts the profile page; Live's layout is the
// familiar one) and avatars.
ddiff --git a/server/events.js b/server/events.js
iindex 52989b6..f7e31ed 100644
---- a/server/events.js
++++ b/server/events.js
@@@ -14,9 +14,9 @@
* Off unless EVENTS_URL and OV_OAUTH_CLIENT_SECRET are set (EVENTS_PUBLISH=off disables it).
*
* The event types are the forum's own namespace (plan T10 D3: the forum's contracts are Space's).
-- * OpenVibe.Contracts must publish the space.thread.created / space.post.created / space.moderation.action
-- * payload contracts before this producer is switched on: Events refuses an event type it has no contract
-- * for, and both this and the Discord relay's Events worker are off without EVENTS_URL.
++ * openvibe-contracts v0.110.0 publishes the space.thread.created / space.post.created /
++ * space.moderation.action payloads (space.json `eventsProduced`), so Events accepts them; the producer
++ * and the Discord relay's Events worker stay off without EVENTS_URL and OV_OAUTH_CLIENT_SECRET.
*/
const { createClient } = require('openvibe-sdk/core');
const { createServiceTokenClient } = require('openvibe-sdk/auth');