Commits
-
Serve discovery, page heads and cache headers from openvibe-shared (#11)OpenVibers · 4 Oct 2026
cef50a4 -
Bump openvibe-contracts to v0.86.0 and note T10 migration TODO (#10)OpenVibers · 3 Oct 2026
4997063 -
Show and take paste comments on the paste's typed comment thread (#5)OpenVibers · 2 Oct 2026
d7686f2 -
Submissions: a reviewed section for community deliverables (#3)OpenVibers · 2 Oct 2026
e2822a3 -
Community is the only paste authority, moves between pages without a reload, and tells search engines when a page changes (plans T10 J6 and T11). The PASTES_AUTHORITY=live path is gone: the Live paste proxy (server/pastes/proxy.js), the Live client (server/live-client.js), the switch and its config, the local capability fallback and the C-24 references; migration 0002 drops the unread pastes.legacy_media_id/legacy_user_id and paste_comments.legacy_media_id (legacy_id_map stays: identity resolution uses it). openvibe-shared v2.2.0 boost with the release marker; IndexNow with INDEXNOW_KEY (public posts and pastes appearing, changing or going away); a home-page performance budget. test/proxy.test.js proves nothing reads the switch or proxies /api/pastes and the columns are gone. 47/47 (verified twice).OpenVibers · 29 Sept 2026
c4b171a -
The SQLite era is gone (on PostgreSQL since 2026-09-28; no compatibility kept): the one-time migrate-to-postgres script, *_DB_PATH settings (config, .env.example, systemd unit, test helpers), the unused better-sqlite3 dependency and its lockfile entries, and docs, docstrings and STATUS lines about SQLite or its rollback window. Reviewed independently before shipping. npm test 46/46 test files passed.OpenVibers · 29 Sept 2026
e63af62 -
Community on PostgreSQL (ADR-035, roadmap WS-X2, repository pass G3).OpenVibers · 28 Sept 2026
8f021e6 -
npm test no longer counts a skipped test as passed (roadmap WS-Q task 7; openvibe-shared/test-runner, Shared v1.25.0). test/run.js counted every file that exited 0 as passed, so a file that printed that it skipped its work and checked nothing still read as green. It is now the shared runner (same files, one at a time as before, 60 s timeout per file): a test prints "<label>: skipped (<why>)" for what it could not run, and that file is listed with ○ and its reasons and not counted as passed; --strict makes a skip fail the run. No test here skips anything. openvibe-shared is pinned at v1.25.0 (from v1.22.0; 1.23 and 1.24 add the web runtime, release-watch fixes and the readiness skip, and /api/ready answers as before because its db check really runs; the README follows). npm test (Node 22) 49/49.OpenVibers · 28 Sept 2026
581d805 -
README and STATUS.json are current (roadmap WS-U task 3): the README gains Purpose (the opening overview), Owns, Does not own, Depends on, Acceptance (what the test files prove), and Security (SECURITY.md, auth, private data, egress, secrets by name) sections. Capabilities lists all twelve capabilities in the manifest (space, thread, vote and Pulse reads were missing), names the v0.71.0 pin (was v0.49.0) and the grants Community uses at Network, Media, VIP and Events. Deploy says production deploys with sudo ovhost deploy community (not git pull and a restart), runs as ubuntu, and gives the rollback; the layout names openvibe-shared v1.22.0. STATUS.json is new, in the shape of Search's, updated 2026-09-28.OpenVibers · 28 Sept 2026
2da3501 -
Per-actor rate limits at Community's API routers (roadmap WS-R task 4, openvibe-sdk v0.12.0 limits). server/actor-limits.js makes one limiter per app, used by the paste, comment, forum (spaces, posts, groups), Pulse and relay APIs once each resolves its viewer and checks the route's capability. It counts a person as user:usr_… whether they call with their own token or a service or app names them in X-OV-Subject; a first-party service relaying a signed-out visitor by the address it forwards (as the per-address /api/ limit already does for Live's calls); a service or app acting as itself (moderation, AI output such as Live's AI pastes, Pulse) by its principal; a signed-out browser by address. A first-party service reading for itself is not counted on reads, since its pages speak for all its visitors and the per-address limit already bounds it. Past a limit a route answers 429 problem+json rate_limited with Retry-After before any work, logs one [Limits] line and counts community_rate_limited_total{limit,window}.OpenVibers · 28 Sept 2026
52d923a -
Pulse shows game milestones (roadmap WS-M task 2, PF7): Community subscribes to network.module.updated, and a person's games.progress.summary write (level is a public field in Contracts) updates game_progress. A later write crossing a multiple of 5 becomes one Pulse item, 'Reached level 10 in Scraplandia' (Games · level), with the person as actor. The first write seen is only a baseline, so there is no stale announcement; a level going down (another character) announces nothing; exactly once through the inbox; only the record's public fields are read.OpenVibers · 26 Sept 2026
90edad6 -
N-1 tests (roadmap WS-P task 11): the previous release's clients against this server, and its SQL against this schema. test/n-1.test.js boots this checkout as production runs it (pastes authority community, the shared database) with its Live, Network and Media mocks, on a database created from the previous release's schema, so Community's migrations run over it, and replays test/fixtures/n-1/client.json inside openvibe-shared's mixed-version matrix (release-compat assertMixedVersion): 78 requests (community.js, the templates' forms, the openvibe-sdk community client, and every link, script and form of ten pages that release served: /, /pastes, a paste, a space, a thread, a comment thread, /search, /pulse, /new, /my; every call anonymously, reads signed in with the ov_token cookie), each answered compatibly (any 2xx for a 2xx, the same status otherwise, JSON where there was JSON, redirects to the same place, every response field the client reads with a type it had). Then every statement in test/fixtures/n-1/worker.json (175: what that release ran, plus its SQL literals) must still prepare on the migrated schema, and no old INSERT may miss a new NOT NULL column without a default. Fixtures recorded from 19441aa, the release in production; refresh after each deploy with `npm run n-1:record [ref]` (a temporary worktree of the release, booted, seeded, replayed). The harness is the file Live, Chat and Media share (test/n-1/harness.js); test/n-1/service.js and boot-child.js are Community's part. In npm test, so in CI, about 2 s, no git history or network. Checked by breaking it: a paste's views as a string fails it.OpenVibers · 26 Sept 2026
0a3b5ea -
A space can attach a chat room on OpenVibe.Chat (roadmap WS-I task 4): its owner (the space's creator, or the creator whose members' space it is) or discussion staff attach one room by address or link, from the space page without JavaScript (POST /s/:space/chat-room, /chat-room/detach) or PUT/DELETE /api/v1/spaces/:space/chat-room; the space page (feed and forum style) links it with its kind and "members only" for a private room. Each side checks its own end: Community the space, Chat that the same person manages the room, because Community asks Chat with the person's own Network token (server/chat-rooms.js: POST OV_CHAT_INTERNAL_URL/api/chat/rooms/:room/attachments { service: community, resource, title }), so no service grant or capability is involved and services cannot attach (moderator services may detach). Chat's refusals come back as chat_room.not_owner (403), chat_room.not_found (404, also a private room the person is not in) and chat_room.unavailable (503/502), shown as a notice on the page. Attaching the same room again is a no-op, another room replaces it (Chat is told the space let go of the old one, best effort), detach is idempotent and asks Chat to drop its side when the person may. The link is kept in space_chat_rooms (CREATE TABLE IF NOT EXISTS: the room's id and slug, and its name, kind and visibility as Chat answered); spaces in the API carry chat_room. No event yet (no contract has one). Test: chat-room.test.js against a stub ChatOpenVibers · 26 Sept 2026
50668b7 -
Discord relay both ways, as an Events worker, with an external message map (roadmap WS-J tasks 5 and 6): replies follow new threads to Discord, edits PATCH and deletes (or gating a thread members-only) DELETE the Discord messages through relay_message_map (Discord message <-> thread/post per mapping, unique both ways; creates are sent with ?wait=true to learn the message id, and a mapping can post into a Discord thread via thread_id). Creates are queued by an Events worker that reads Community's own community.thread.* / community.post.* from OpenVibe.Events' pull API with a cursor kept in relay_cursors (moved in the same transaction as the deliveries; first start begins at the head; dedupe keys make replays a no-op); without EVENTS_URL / the client secret, or with DISCORD_RELAY_EVENTS=off, the forum queues them as before. Inbound: a Discord gateway client on Node 22's built-in WebSocket (IDENTIFY/RESUME, heartbeats with zombie detection, RECONNECT, INVALID_SESSION, fatal close codes; intents GUILD_MESSAGES | MESSAGE_CONTENT) behind DISCORD_RELAY_INBOUND=on and DISCORD_BOT_TOKEN turns replies to relayed messages in mapped channels into posts with origin discord (no author subject, the Discord name in posts.relay_author, a Discord badge), rate- and size-limited with mentions defused; edits and deletes on Discord follow through the map. Loop prevention both ways (origin discord never goes out; webhook, bot and system messages never come in). Dead letters: failed deliveries keep their error; staff retry or drop them, and inbound failures (ids and reason, never text) are listed and dismissed at /api/v1/relay (new: status, drop, inbound). Off by default and inert without the owner's webhooks, mappings and bot token; owner steps in docs/discord-relay.md. Schema: relay_deliveries rebuilt once (post_id, action, source, event_id, statuses dropped/skipped), relay_mappings gets discord_channel_id/discord_thread_id/inbound, posts gets relay_author, new relay_message_map, relay_cursors, relay_inbound_failures. Tests: relay.test.js, relay-events.test.js (fake Events pull server, the whole outbox -> Events -> worker -> Discord path), relay-inbound.test.js (fake gateway), shutdown.test.jsOpenVibers · 26 Sept 2026
f94d83a -
Graceful stop (WS-P lifecycle follow-up): SIGTERM used to close only the HTTP server (which waited on 65 s keep-alive connections until the 5 s fallback) while the events outbox, the Discord relay, the Pulse subscription retries and the profile and search-document scans kept running into the exit. Now (server/graceful.js): the subscription retries, the community.profile scan and the search-document scans stop; the server stops taking connections, closes idle keep-alive ones and lets requests in flight finish with Connection: close (4 s at most); then the profile scan in progress (it stops between people), the relay's drain and the outbox's send are awaited (unsent rows stay for the next start), community.db closes (db.closeDb) and the process exits 0, within 5 s (exit 1 past it). events.stop(), relay.stop() and profile.stop() resolve when their work in flight ends and start nothing after. test/shutdown.test.js: the real process with every worker on, SIGTERM with a request in flight and an idle keep-alive connection: refused afterwards, the request answered, every worker reported stopped, exit 0 in < 5 sOpenVibers · 26 Sept 2026
fc7aaf6 -
Platform blocks (WS-E task 5, Contracts 0.49.0): Community consumes network.block.changed into a newest-revision projection and refuses (403 community.blocked, plain message on the no-JS forms) a reply in a thread whose author blocked you, a reply to a comment whose author blocked you, and a comment on a paste or post whose owner blocked youOpenVibers · 25 Sept 2026
0cce476 -
Forum boards next to feeds: each space is a forum (vBulletin/SMF style: a grouped board index with topics, posts and the last post; topic tables with replies, views and the last post, sticky first, bumped by replies; posts beside the author's panel with Quote) or a feed (votes, hot/new/top); votes and Facepunch-style ratings (Agree, Winner, Funny, Informative, Friendly, Sympathy, Dumb, Disgusting, Bad reading, Late; one per person per post) switch per space; pastes attach to posts as cards and every paste has Discuss in a space; threads crosspost between spaces; moderators create spaces, groups and child boards and change styles; General, Help and Off-topic are forums, Feedback, Roadmap and Showcase feedsOpenVibers · 25 Sept 2026
a1c3b23 -
Images on forum posts as med_ references (WS-J task 2): up to 4 PNG/JPEG/GIF/WebP images (by content, 8 MB, metadata stripped) per thread or reply, stored through OpenVibe.Media's Object API v2 (init, content, complete) as public objects the person owns; POST /api/v1/spaces/:space/attachments then attachments: [media_id]; the no-JS forms upload and attach in one step; the roadmap marks it doneOpenVibers · 25 Sept 2026
8708672 -
Categories, feature requests and a public Roadmap space (WS-J tasks 1 and 8): categories per space (Feedback: Ideas, Bugs, Questions), filters by category and status, Feedback threads are requests (open to votes, statuses set by staff), the Roadmap space follows docs/roadmap/public.json at every boot (one thread per item, summaries edited in place, replies and votes kept), staff-only roadmap items; API routes, no-JS pages and formsOpenVibers · 25 Sept 2026
834a14d -
openvibe-shared v1.5.1 (Track R release manifest), openvibe-contracts v0.33.0OpenVibers · 23 Sept 2026
78f2f9b -
Paste list for feeds: GET /api/pastes takes sort=top (views, a like worth five views, newest first on a tie), since= (created at or after; ISO 8601 or 'YYYY-MM-DD HH:MM:SS' UTC, compared with datetime() so imported ISO timestamps work; an unreadable value is ignored) and pinned_first=0 (a pinned paste stays in sort order instead of leading every list). With the existing origin=user|ai this is what OpenVibe.Live's Content feed (people's pastes) and Moments feed (AI pastes) read: a list merged with VODs and clips by date or score needs every source in its own sort order, and "top this week" needs a window. Defaults are unchangedOpenVibers · 23 Sept 2026
6d534d8 -
Members-only discussion through OpenVibe.VIP: a forum space or a single thread can be for one creator's VIP membersOpenVibers · 23 Sept 2026
57d1dd4 -
Live's VOD and clip comments become Community threads (Wave 5 exit: Live and a second product share one thread)OpenVibers · 23 Sept 2026
7d7cc3d -
Docs: STATUS.json and README match production (2026-09-23)OpenVibers · 23 Sept 2026
466eaba -
Discord relay: a mapping may only name an allow-listed webhook variable (DISCORD_WEBHOOK_*, or exactly the names in DISCORD_RELAY_WEBHOOK_VARS). Staff could point the relay at the URL in any environment variable (an internal service's base URL) and learn which variables are set; such mappings are now refused when made, never sent to if already stored, and never reported as configuredOpenVibers · 23 Sept 2026
be48b73 -
Unlisted pastes get slugs nobody can guess: a new unlisted or private paste (and a fork of one) gets adj-noun- plus 16 random base62 characters (~2^95) instead of the ~1.5M adj-noun-NN space that could be walked; public pastes keep the short form, service-named slugs are unchanged, and existing slugs keep workingOpenVibers · 23 Sept 2026
2e6f43b -
Comment threads cannot be enumerated: every thread gets an unguessable access id (cth_ + 128 random bits, filled in for existing threads on boot, unique index); browsers address threads only by it and get it as the thread id from resolve, while the sequential id keeps working for services (Blog, Wiki, Deals, Reviews resolve by EntityRef with a service token and store it), so walking ids no longer reveals the refs and comments of unlisted or private entitiesOpenVibers · 23 Sept 2026
faa08c2 -
Observability (Track O): GET /metrics (loopback only) with HTTP golden signals by route template, process metrics and release_info; /api/ready built on openvibe-shared/ready (db required; Network key, Live or Media optional -> degraded) instead of an unconditional {ready:true}; nginx refuses /metrics; openvibe-shared v1.3.0OpenVibers · 23 Sept 2026
b492398 -
openvibe-shared is the pinned OpenVibe.Shared v1.0.0 release (vendor/ is gone); openvibe-contracts v0.7.0 knows the Wave 5 capabilitiesOpenVibers · 23 Sept 2026
458d44b -
Wave 5: typed comment threads, forum (spaces/threads/posts), Discord relay, PulseOpenVibers · 23 Sept 2026
139aedd