Skip to content
-
Restore 'shipped' on the home page, /updates and chat deploy notices: since the release layout (C-76) the release worktree is root-owned, so git refused the service user ('dubious ownership') and all three read nothing; their read-only git calls now pass -c safe.directory=*OpenVibers · 24 Sept 2026
654ad1ab
-
Kiosk companion and hardware scripts moved to OpenVibe.Extensions (ADR-023, W18): browser-extension/ and hardware/ keep only redirect READMEs pointing at OpenVibe.Extensions kiosk-companion/ and hardware/ (moved unchanged at 9c5aa64)OpenVibers · 24 Sept 2026
ce6a7332
-
Production runs the release layout (C-76 done 2026-09-24 05:51 UTC): deploy from /opt/openvibe.live/current; the old checkout files are stale; release ids come from the directory name; the host inventory runs git for Live as rootOpenVibers · 24 Sept 2026
9c5aa64f
-
release.json names the release in the release layout: the service user cannot run git in a root-owned release worktree, so the manifest said 0000000 (open tabs could not tell releases apart); RELEASE_COMMIT, else the <time>-<sha> release directory name, supplies itOpenVibers · 24 Sept 2026
f15023a8
-
Unit description matches production (no 'Free' copy) in both the in-place and release unitsOpenVibers · 24 Sept 2026
9f7f36c7
-
CI calls the shared test workflow (Track Q): OpenVibe.Shared test.yml@e8b0caf (install, node --check over server/, scripts/ and public/js/, npm test with the size budgets, openvibe-contracts-check) instead of a copy of those stepsOpenVibers · 24 Sept 2026
862bc470
-
VIP first for subscriber perks (W10, proof flow 3): with Billing as the money authority, whether a viewer is subscribed to a channel (channel state, chat and AI perks) is OpenVibe.VIP's entitlement answer through openvibe-sdk/vip (v0.7.0) with Live's service token (vip.entitlement.check); Billing's own answer stands in only when VIP cannot say, and the purchase check still asks Billing. LIVE_VIP_ENTITLEMENTS=off asks Billing only. Inactive while Live is the authority. Test in billing-authority.test.jsOpenVibers · 24 Sept 2026
e08bbecd
-
Crawlable pages for the Content and Moments feeds (D44): /content?page=N and /moments?page=N render page N of the cursor feed in the initial HTML (following N-1 cursors, each page cached, 20 deep), self-canonical, with newer/older rel=prev/next links, continuing ItemList positions and a page breadcrumb; past the end is not rendered. The SPA keeps its infinite scroll. test/feed-pages.test.jsOpenVibers · 24 Sept 2026
d4ccdfb0
-
Home cards say when the AI inferred a category (roadmap 33.4): live stream cards, featured cards and the Star card show 'Gaming · inferred' with a tooltip when the category is the stream's or channel's ai_category, as the channel and VOD/clip pages already do; /api/home star carries category_inferredOpenVibers · 24 Sept 2026
03e38148
-
Staff gates ask the contracts staff map (D05, ADR-022): permissions.can(user, 'staff.<area>.<action>') and requireCap() over openvibe-contracts v0.35.0 (staff-roles.json; issued staff_caps claims win when Network sends them). Every actor role comparison in server/ now names its capability (hardware, streams, assets, site configure, moderation calls/pastes, limits exempt, content view_private), and the role helpers (admin panel, users, secrets, money, bans, logs, force-end, …) answer through the map; /api/auth/me capabilities carry staff_caps. What remains compares a target's rank. Two answers now follow the map: global moderators may see private VODs and clips on stream pages (staff.content.view_private), and only admins skip the per-IP call-socket cap (staff.limits.exempt). test/staff-capabilities.test.js pins helper-map parity for every role and fails on any new raw role checkOpenVibers · 24 Sept 2026
ff7c5418
-
Egress on openvibe-shared 1.6.0: the address policy and connect-time lookup come from openvibe-shared/egress (the rule Events and Tools use; now also refuses 3fff::/20, 5f00::/16, NAT64 64:ff9b:1::/48 and internal names at lookup), Live keeps its redirect-checking fetches and the child-process proxy on top. Shared 1.6.0 also fixes release beacons keyed by the proxy's addressOpenVibers · 24 Sept 2026
b3602885
-
Kiosk omnibar titles through OpenVibe.Tools (platform S9): /api/kiosk/site asks the opengraph tool's run API with Live's service token (tools.tool.run on openvibe.tools; anonymous tier without one) and decodes entities in the title; Live fetches the page itself only when Tools refuses or is down. The DNS public-address check still runs first. test/kiosk-tools.test.jsOpenVibers · 24 Sept 2026
cf72bd94
-
SECURITY.md: how to report a vulnerability ([email protected], 7-day reply, scope, supported versions)OpenVibers · 24 Sept 2026
12c1c119
-
Staff scope on streams: an admin may moderate another streamer's slot or stream (edit, end, delete, read status) but never the site owner's, and nobody acts as another streamer: regenerating a stream key, the ingest endpoint, going live on another's slot, heartbeats, call settings and WHIP publishing are the streamer's alone (they had an admin bypass). test/staff-stream-scope.test.jsOpenVibers · 24 Sept 2026
80f42213
-
Merge L1: AI Moments noindex + canonical to the source VOD, AI attribution in the UI, paste canonical handover, server-rendered channel/VOD/clip pages, llms.txt, per-channel AI derivation opt-out, creators above the about blockOpenVibers · 24 Sept 2026
25c12797
-
docs/dashboard.md: the AI Moments sub-tab, what My Clips holds, and the channel's 'AI Moments from my streams' switch (what it stops, what stays) and the 'inferred' category marker.OpenVibers · 24 Sept 2026
9721fea4
-
Merge L2: restream and RobotStreamer slot-only, anonymous Go Live gate, deterministic loyalty keys, persisted Tips delivery idempotency, internal-key hardening, narrow vibe-coding scope, HoboQuest remnants removedOpenVibers · 24 Sept 2026
b91058fe
-
Media requests paid in Vibes on Billing: when Billing never answers (an 'unknown' outcome) the request row is kept out of the queue with charge_state 'unknown' instead of being deleted, so the billing action keyed live:media_charge:<request id> still points at a request the staff money page can settle; the unknown-charge note names the request's currencyOpenVibers · 24 Sept 2026
1240dea5
-
Browser smoke: the guest /broadcast gate check ignores session plumbing (a guest's POST /api/auth/refresh) and analytics beacons when it looks for writes; only the page acting counts. Full smoke (signed in with a local token, and as a guest) passes against a scratch serverOpenVibers · 24 Sept 2026
411fa858
-
Follow-ups from running the pages in a browser: the sitemap names channel pages from Live's accounts (Media VOD and clip rows carry user ids, not usernames, so /@user pages were never listed; banned accounts stay out); the channel page sets its tab title to the channel (the client reset it to the site default on boot, replacing the server-rendered title, including for crawlers that run scripts); the clip page's 'AI clip · from <streamer>'s stream' / 'Clipped by' line sits right under the title instead of below the source box; the client's default tab title and the home tour's 'Free restream' chip drop 'free' (owner copy rule); server-rendered durations read h:mm:ss from an hour up. test/seo-ssr.test.js checks the sitemap's channel pages and the duration format.OpenVibers · 24 Sept 2026
66a2b1b3
-
Service tokens to Network on link-account, identity legacy-map and resolve-batch (daily identity sync), coins/stats and resolve-anon, which Network guards by capability since 2026-09-24; a refused token falls back to the internal key once (compatibility register C-50..C-57)OpenVibers · 24 Sept 2026
680d3832
-
Legacy HoboQuest remnants are read-only in Live: viewing a chat profile no longer creates a game_players row. The profile card (GET /api/chat/user/:username/profile, and /internal/chat-context/users/profile that OpenVibe.Chat reads) called the old game engine's getPlayer(), which INSERTed a placeholder row for every profile opened (production 70, newest 2026-09-19); they now read db.getLegacyGameProfile(), which never writes and returns the same skills block for legacy players. The engine (server/game/game-engine.js), its item tables (items.js), the game schema and scripts/migrate-rs-companion.js (which wrote game_* tables) are retired, since OpenVibe.Games owns the game and imports Live's legacy rows. Chat tags move to the read-only server/chat/tags.js (catalog, tables, owned and equipped tags for chat lines, history and Chat's decor); the Tag Guardian fight, tag shop and grant/equip writers had no caller left and are gone, as is test/test-tags.js, which only exercised them. The global-chat route's require of the non-existent ../game/cosmetics (always caught, so cosmetics never attached) now uses the real cosmetics module. test/legacy-game-readonly.test.jsOpenVibers · 24 Sept 2026
ee70c40e
-
No 'free' or $0 in Live's home metadata (owner copy rule; audit 32.2 row 2779): the server-rendered home title, description, heading and Organization description say open-source and community run instead, and the shell's SoftwareApplication JSON-LD drops its offers.price '0'. test/seo-ssr.test.js checks the home head and body (free speech stays fine).OpenVibers · 24 Sept 2026
b6d1c9b6
-
The home page leads with live content and creators (roadmap 32.7, critique 1): the creator rows (Recently Online, Recent VODs, Recent Clips, Recent Pastes) move from under the site's introduction to above it, after the digest, star and pulse and before AI Moments (33.6: made, then derived), so the restream tour and the collapsed About banner follow what people made. Live Now stays first; nothing is removed, ids and header-before-grid pairs are unchanged, the home budgets hold (HTML 83.1 KB). test/home-order.test.jsOpenVibers · 24 Sept 2026
74616a76
-
Vibe-coding publication needs the narrow vibe_coding_publish scope: /ws/vibe-coding/publish (publish-server.js) and the /api/vibe-coding writes (auth.js token scope table) no longer accept the broad stream scope, which let any stream-control token (live state, restreams, VODs, clips) publish a coding feed. Tokens made with the GitHub Copilot Companion preset (read + vibe_coding_publish) keep working; session sign-in is unaffected. Moving publication onto Network project credentials, surfaced in OpenVibe.Codes, is later work. docs/vibe-coding.md and docs/api-tokens.md say so; test/vibe-coding-scope.test.js connects to the real endpoint with real hbt_ tokens (stream-only closed with 4403, publisher ready) and checks the REST scope tableOpenVibers · 24 Sept 2026
897f3561
-
A streamer can turn AI Moments off for their channel (roadmap 33.7/33.10): channels.ai_derivation_enabled (on by default, idempotent ADD COLUMN; db.isAiDerivationEnabled, true for an account with no channel row), set through PUT /api/streams/channel and a new dashboard Home card, 'AI Moments from my streams'. Off, the auto-clip job skips the channel's live streams before looking at the recording, leaves its VODs out of the backfill pool and clipVodMoment cuts nothing; the AI moments job never picks its VODs (no moment pastes, no clips from them); the stream-memory job posts no 'caught live' pastes (memory capture, the AI overview and captions are unchanged); and the after-show report is the stats-only one with no model call. Moments already made stay until deleted from Content > AI Moments. The AI-assigned category is marked 'inferred' on the channel page (live, offline and slot switch; built with DOM nodes) and on the VOD/clip detail chips (stream_category_inferred from the API). llms.txt says a channel can opt out. Also: the Offline Screen card read data.channel from GET /streams/channel, which answers the channel row itself, so it always showed the default. test/ai-derivation-optout.test.jsOpenVibers · 24 Sept 2026
2a7a0ae5
-
Internal-key routes share one trust rule (server/net/internal-key.js): loopback only and INTERNAL_API_KEY compared in constant time. POST /api/cosmetics/internal-unlock checked only the key, so anyone holding the key shared by Network, Live, Media and Tools could unlock paid cosmetics through the public edge; it now refuses anything with X-Forwarded-For, X-Real-IP or CF-Connecting-IP like /internal/* and the service-token guard (which now imports the same viaProxy). /internal/* and /internal/analytics-summary compared the key with !==; all three use internalKeyMatches (both sides hashed, so neither content nor length leaks through timing). test/cosmetics-internal.test.js checks the edge headers, wrong keys of equal and longer length, the /internal routes, and that no === / !== key compare is left in server/OpenVibers · 24 Sept 2026
912b87c5
-
Tips deliveries stay idempotent across a Live restart: the in-memory done Map in server/tips/delivery-routes.js is now the tips_deliveries table, keyed by Idempotency-Key with the stored answer. A key is claimed before its effect runs; a repeat of an answered key returns the first answer and does nothing, a repeat while the first attempt is still running gets 409 (Tips retries), a claim older than two minutes (left by a crash) is taken over, and any answer but 200 gives the key back so the retry runs it. Answers are kept 7 days and pruned at most hourly. test/tips-delivery.test.js restarts the route module between deliveries and checks the same answer with no second chat line, the in-progress 409 and stale takeover, the released key on a refusal, and pruningOpenVibers · 24 Sept 2026
4ebc638a
-
Loyalty ledgers use deterministic per-event idempotency keys (ADR-012 rule 5). Media requests: a paid request is written first (status failed, charge_state 'charging', out of the queue and history) and its charge is keyed by its id: OpenCoins and channel points live:media_req:<id> (was Date.now()+Math.random()), Vibes on Billing live:media_charge:<id> linked to the request from the start (was a random UUID); it joins the queue once paid, a refused charge removes the row, and a wallet that never answers (asked twice with the same key) leaves it 'unknown' for the new media-charge-reconcile job, which charges again with the same key (a replay if it landed) and refunds it, so the viewer ends where they started. Channel points: every debit and credit goes through db.applyChannelPoints with a key in the new channel_points_log (a repeated key moves nothing, a reused key for another event is refused, a refused debit leaves no row): watch = watch row + minute, chat = the user's minute (holds across a restart), follow = user + streamer, bonus = claim window, media = request id, redemption = redemption id (limits are checked and the row created and paid in one transaction, so there is no take-then-refund), and a streamer rejecting a redemption twice refunds once. Admin OpenCoins grants are recorded first and keyed live:admin_grant:<grant id> (was Date.now()+Math.random()); an Idempotency-Key repeat is the same grant. test/loyalty-keys.test.js shows retries never spend or credit twice; billing-authority checks the Billing key and its replayOpenVibers · 24 Sept 2026
91383003
-
/llms.txt for Live (roadmap 32.4/32.5, 33.8): plain text (llmstxt.org shape) saying what OpenVibe.Live is, its public pages and the JSON behind them (/content and /api/content/feed, /moments and /api/content/moments, /@user?page=N, /vod/<id>?t=<s>, /clip/<id>, pastes on OpenVibe.Community), the API docs (/documentation, /docs and the WHIP, broadcasting, API token, chat, VOD/clip and architecture docs that exist), the sitemap, and how people's work is kept apart from AI Moments (labelled, credited to no person, noindex,follow, canonical to the source VOD at the moment, 'ai': true in the JSON). Served by the SEO module before the SPA fallback, cached an hour. test/llms-txt.test.js checks the links resolve to real docs and that it has no free/$0 copy.OpenVibers · 24 Sept 2026
faf49f8f
More commits