Commits
-
Shared 1.28.0: openvibe-shared/config on PostgreSQL. Given an openvibe-sdk/db handle, createConfigStore uses config-pg.js, the same store on the async handle (immutable revisions, atomic activation, last-known-good restored when onActivate fails, redacted secrets with a per-namespace fingerprint key, legacy import) and returns a promise of the store; get() and revision() stay in memory, the rest is async. configSchema() is the DDL for the service's migrations. adminRoutes awaits either kind of store; the better-sqlite3 path is unchanged. test/config-pg.test.js runs every scenario of config.test.js on PGlite (openvibe-sdk v0.20.4 as a dev dependency; its made-up secrets are allowlisted like the original's). npm test 41/41.OpenVibers · 28 Sept 2026
116e07a -
Shared 1.27.0: openvibe-shared/express-async. Express 4 ignores what a handler returns, so a promise an async handler rejects (a database error, a thrown problem) became an unhandled rejection, and Node 22 ends the process on one; the move to PostgreSQL made most handlers async (nine services had 5-41 such routes, confirmed to exit). routeAsyncErrors(app) patches the app's own Express 4 Layer once so the rejection reaches next(err) and the service's error handler answers, as a synchronous throw always did; error handlers too; a no-op on Express 5. instrument() calls it, so every service is covered by a pin bump. npm test 40/40.OpenVibers · 28 Sept 2026
cded2bc -
Shared 1.26.0: async gauges. A gauge's collect() may return a promise (a database read, now that services are on PostgreSQL, ADR-035). The /metrics handler awaits every async collect together through the new registry.metricsAsync({ timeoutMs = 2000 }); one that rejects or runs past its budget is left out of that scrape, never reported stale, as a throwing one already was. The synchronous registry.metrics() is unchanged and leaves an async gauge out. The handler is an async function; its callers need no change. npm test 39/39.OpenVibers · 28 Sept 2026
49ce9d6 -
Shared 1.25.0: openvibe-shared/test-runner, no fake green in npm test (roadmap WS-Q task 7). Every service carried its own test/run.js, and each counted a test file that exited 0 as passed, including one that printed "…: skipped (no ffmpeg)" and checked nothing, so "150/150 test files passed" could hide skipped work. The runner is now one module, main({ dir, timeoutMs, pad, hide, env }) (run() returns the results): the copies' behaviour (each *.test.js in its own process, a few at a time, NODE_ENV=test, a timeout per file, name filters, the last 40 lines of a failure minus hide lines), plus skips: a test prints "<label>: skipped (<why>)" for what it could not run (the line OpenVibe.Host's acceptance runner already reads), and that file is listed with ○ and its reasons and not counted as passed; the summary reads "148/150 test files passed, 2 skipped (…)", and only a run with nothing skipped says N/N. Skips alone exit 0; --strict or OV_TEST_STRICT=1 makes them fail. Exported as ./test-runner; this package's test/run.js uses it; test/test-runner.test.js covers pass, skip, partial skip, failure, hidden lines, filters and strict. README and CHANGELOG describe it. npm test (Node 22) 39/39.OpenVibers · 28 Sept 2026
919c108 -
Shared 1.24.0: no fake green in readiness (roadmap WS-Q task 7). ready.js knew only ok and fail, so a check whose feature was not configured had to claim ok (Network's Discord bot, Media's events outbox and News's source pull did, as production's /api/ready shows) or fail and turn the service yellow for a setting. A check now returns skip(reason, detail?) (exported) or { skipped: reason }: it reports status skipped with the reason, never ok, and is listed in the body's new skipped array. A skipped optional check leaves a service whose other checks passed ready; a skipped required check is also degraded (yellow, still HTTP 200: nothing failed); and a service is ready only when at least one check really passed, so one with no checks or every check skipped is degraded (before: ready). test/ready.test.js covers each case; README and CHANGELOG describe it. npm test (Node 22) 38/38.OpenVibers · 28 Sept 2026
48b7443 -
v1.23.1: two release-watch fixes found by the release-lifecycle acceptance scenarios (D46, roadmap WS-P task 16; OpenVibe.Host scripts/release-acceptance.js), and tests for scenarios 4, 9 and 14.OpenVibers · 27 Sept 2026
23d41bf -
v1.23.0: web runtime, a site's feature loader and route lifecycle (roadmap WS-P task 6). New browser file web-runtime.js (OVWebRuntime.create; files.js, export openvibe-shared/web-runtime; 6.1 KB brotli, budget 6.5 KB): OpenVibe.Live's public/js/ov-loader.js made shareable. It keeps the feature registry and routes, once-only scripts and stylesheets (the server's tags adopted), versioned URLs, fragments, route generations, scopes, intent and idle prefetch, stubs and the route retry box. New: transactional asset groups (a feature commits only when every script loaded; a failure withdraws that attempt's stylesheets unless another feature wants them and removes the failed tag; a retry fetches only what is missing, nothing runs twice); scopes that refuse and count late registrations, scope.fetch on the route's signal, child scopes, held() counts, fired timeouts released; a prefetch budget (count, and bytes where sizes are known); diagnostics() and leaks() (duplicate tags, failed and rolled-back assets, late registrations, what the route holds). showRouteError builds DOM; another origin's assets are keyed by origin and path. Tests: linkedom (tags load or fail on cue) and headless Chrome (a slow script still in order, a real 404 rolls back and the retry completes, a route's interval stops and its fetch aborts).OpenVibers · 27 Sept 2026
1dfdc41 -
Pins: openvibe-contracts -> 0.61.0 (network.notification.created@1, identity.realtime-ticket-claims@1, network.realtime-ticket-result@1)OpenVibers · 26 Sept 2026
dbf9d39 -
v1.22.0: the notification bell in realtime, off by default (roadmap WS-E task 3, WS-F task 1; openvibe-contracts 0.61.0, ADR-005 amendment 2). New browser file notification-live.js (OVNotificationLive, 2.4 KB brotli, budget 3 KB): a realtime ticket from Network (POST /api/v1/realtime/ticket, Bearer or the openvibe.network cookie) for every (re)connect, then Events' /realtime/stream?topics=network.notification.*&ticket= without credentials, resuming with last_event_id; only the ticket's person's events count; gaps reported; errors close and back off from 2 s with jitter, ten in a row stop it until online; hidden 5 min closes, shown resumes; CSP refusal, 401/403 and 503 stop it. notification-ui.js (budget 13 KB) loads it from its own directory with init({ realtime: true }) (navbar: notificationsRealtime: true): an event re-reads the count once per burst (and again after a poll in flight), a gap also reloads open lists, the 15 s poll runs every 2 min while the stream is open; setToken() restarts it; realtimeState(). files.js and exports list it; browser-harness exports openPage. Tests: linkedom (subscribe, resume from the cursor, gap -> refetch, CSP-blocked -> polling, guessed topic yields nothing) and headless Chrome with a real EventSource (drop and resume with nothing lost or repeated, retention gap, another person's event ignored)OpenVibers · 26 Sept 2026
3282427 -
v1.21.0: browser harness checkUnreachable (ADR-024, roadmap WS-E task 1): openPage({ block }) fails every request matching a pattern, and checkUnreachable(url) reports whether a page still paints (200, settled, text, a --accent token, a background) with openvibe.network unreachable; blocked requests are not page errors. Tested in headless ChromeOpenVibers · 26 Sept 2026
749cbcf -
v1.20.0: release manifest 1.2.0 (roadmap WS-P task 7, openvibe-contracts 0.60.0): createRelease serves client_generation, min_client_generation (env MIN_CLIENT_GENERATION) and shell { version, components }; the meta tag carries data-generation; a tab below the minimum generation reloads when safe (required) and a changed shell never goes in place (it prompts). Contracts devDependency 0.60.0OpenVibers · 26 Sept 2026
36ac2da -
v1.19.0: the update matrix, complete (roadmap WS-P task 8): release-update sends ov:content-dispose before a region is replaced so a widget inside drops its listeners and timers (ov:content-updated follows to mount it again); tests cover every row (style swap and ov:styles-updated, revision-aware content with scroll kept, widget disposal, busy deferral, prompt, security minimum); the README lists the matrixOpenVibers · 26 Sept 2026
d8693c9 -
v1.18.0: update telemetry (roadmap WS-P task 14): release-watch counts the update prompt (prompted: optional, required, window, contract) and beats every 5 minutes with a random in-memory tab id and its release, saying ended on pagehide; the collector keeps tabs heard from in 12 minutes as release_client_sessions{generation=current|older} against the release the process serves. release-watch stays under its 5 KB brotli budget (4.96 KB) by shortening commentsOpenVibers · 26 Sept 2026
e1f7441 -
v1.17.1: release-watch acts on a release notification only when its origin (when given) is the page's own; Sites' placeholders reuse product service idsOpenVibers · 26 Sept 2026
db02e50 -
v1.17.0: release-watch hears about releases over the Events realtime plane (WS-P task 9, ADR-016 amendment 1)OpenVibers · 26 Sept 2026
17a32e4 -
v1.16.1: the OV mark moves for its intro, on hover/focus and while busy, not forever (browser check, WS-Q task 3). Its endless SVG animations (ovmFloat, ovmGlow, ovmComet, ovmDot, the V's SMIL light sweep and the orbiting dots) restyled and re-laid-out every frame and kept every idle page with the navbar 12-29% busy. Now a mark runs for the first 8 s of a visit (kept in sessionStorage, so the next page of a multi-page site finishes the intro instead of starting another), while it or its link is hovered or focused (plus 1.2 s) and while island.js shows activity (data-state busy/ok); otherwise its CSS animations are paused where they are and its SMIL clock stopped, so it keeps its look. Never while the page is hidden, while it is off-screen (IntersectionObserver), with data-static, under prefers-reduced-motion or html[data-ov-motion=reduced] (the V sweep used to run under all of those). A removed mark is unobserved and let go. Headless Chrome after five page loads: 12 running animations and 16.5% CPU before, none and 0% after. test/ov-mark.test.js. Not taggedOpenVibers · 26 Sept 2026
e40dbb8 -
v1.16.0: openvibe-shared/browser-harness (WS-Q task 3, WS-T tasks 3-4): Live's browser smoke suite generalised for any site, headless Chrome over the DevTools protocol with Node's own WebSocket (no dependency). Per route at 390/768/1280 px: HTTP status, console errors (exceptions, console.error, failed loads, CSP), horizontal overflow with the offending elements, scripts requested twice; with JavaScript off: visible text, one absolute canonical, JSON-LD parses and its headline/name is visible (title-style names by their leading part, web pages by their title); axe-core at the widest width (serious/critical fail, moderate reported); a non-HTML answer is judged on its status only. Per site: A->B->A navigation five times (links clicked, so an SPA navigates in place; no back/forward cache) with heap, nodes, listeners, documents, intervals, pending timeouts and sockets sampled after a forced GC, failing growth past BUDGETS that is still growing; idle CPU (script/style/layout), requests and running animations reported. ignoreErrors rules are counted per label. axe-core 4.13.0 from an installed package or jsDelivr checked against a pinned sha384, cached. test/browser-harness-chrome.test.js runs it in real Chrome against a fixture and skips without ChromeOpenVibers · 26 Sept 2026
9fc27a5 -
v1.15.0: openvibe-shared/perf-budget (WS-T task 1): size budgets for a page's first load measured from the running server (HTML, same-origin scripts and stylesheets, raw and brotli; cross-origin assets listed, not weighed), check() and format() for npm testOpenVibers · 26 Sept 2026
55c79b8 -
v1.14.0: openvibe-shared/config, the configuration model (WS-C task 7); openvibe-contracts pin 0.49.0 → 0.52.0 (the tests check every snapshot against common.config-snapshot@1)OpenVibers · 26 Sept 2026
956f7dd -
Pins: openvibe-contracts 0.44.0 → 0.49.0OpenVibers · 25 Sept 2026
5357179 -
v1.13.0: the Sign In button reads at 4.5:1 in every theme (derived --accent-strong/--on-accent-strong; white on #3b82f6 was 3.67:1 on nine sites) and the footer accepts { label, href } items (empty links on Media and Games) — WS-T task 3OpenVibers · 25 Sept 2026
227e3f8 -
Pins: openvibe-contracts 0.42.0 → 0.44.0 (Contracts 0.43.0 and 0.44.0 were released after the previous pin commit, leaving 0.42.0 two minors behind the pin-drift limit)OpenVibers · 25 Sept 2026
fbd4053 -
Pins: openvibe-contracts (devDependency) 0.31.0 → 0.42.0; CI runs the pin-drift checkOpenVibers · 25 Sept 2026
7e96d09 -
1.12.0: openvibe-shared/serve — a site serves its own pinned shared browser files at /shared/* with content-addressed URLs (serve.url, ?v=hash immutable, ETag, CORS-open), so its pin decides what its pages run and the Frame survives an openvibe.network outage; the navbar loads its lazy siblings from its own origin (the network's copy is the fallback)OpenVibers · 24 Sept 2026
82255df -
1.11.1: the footer's shipped line follows the footer's own service (a local or unmapped host showed the whole network); an id that is not a registry id falls back to the hostnameOpenVibers · 24 Sept 2026
d2dbacb -
1.11.0: the OpenVibe Frame — the shared navbar, footer and shipped views are no longer called 'chrome': openvibe-shared/frame (chrome-ssr stays a deprecated alias until 2.0), /api/frame and /api/frame/hit, window.OpenVibeFrame (OpenVibeChrome aliases it), cache key ov_frame_v1; the theme loader's browser-UI colour sync is syncBrowserUi. No behaviour changeOpenVibers · 24 Sept 2026
78883bf -
1.10.0: chrome-ssr shipped() (a home page's pill and recent changes), updatesBody() (a site's /updates page) and shippedScript(): the server-side half of the shared update system, so every site renders the same markupOpenVibers · 24 Sept 2026
16c66ef -
1.9.0: one shipped/update-log system for every site (shipped.js latest/list/log views from data-ov-shipped markup, via the Network changelog proxy; the footer's 'shipped X ago' line and Updates link); fixes: the footer's empty signed-in bar (display:flex beat [hidden]) and 'Sign In' for signed-in people on sites with their own session (a stale or refused token now falls back to sessionUrl; logoutUrl ends the site session; {path} in login/logout URLs)OpenVibers · 24 Sept 2026
c5b47f3 -
1.8.0: shipped.js, 'Recently shipped' for any OpenVibe site from the network changelog on OpenVibe.Blog (per site or network-wide, each line linked to its commit, the latest Patch notes post linked); DOM nodes only, https links only, hidden when empty or failing; served at openvibe.network/shared/shipped.jsOpenVibers · 24 Sept 2026
cccccba -
1.7.0: openvibe-shared/trace, one W3C trace across services: install(app) keeps each request's trace in AsyncLocalStorage and wraps fetch() so calls to loopback or OpenVibe hosts carry traceparent (new span) and X-OpenVibe-Request-Id; provider and user-chosen URLs are untouched; tested against a real loopback serverOpenVibers · 24 Sept 2026
f62f653