Commits
-
The floating-promise check (plan T0): scripts/floating-promises.js parses a repository with acorn and lists every call statement inside a function whose promise nobody awaits, returns, assigns, void-s or chains: a bare call to an async function of the same file or this.f() of an async method (rule a), or a known async API (rule b: .tx(, .transaction(async, db/tx run/get/all/exec/query only where the repository has no better-sqlite3, pool/client.query, .enqueue(, fetch(, fs.promises, .close() on db/pool/client/store). '// floating-ok: <reason>' opts one out (the reason is required). Shared's CI fails on a finding; the shared reusable workflow lists them as warnings until every repository is clean, then fails too. Tests cover each rule, each exemption and the SQLite case. npm test 43/43.OpenVibers · 29 Sept 2026
ba460a2 -
Shared 2.0.0: X-Internal-Key is gone from the shared package (plan T2). internalApiAuth, OpenVibeAuthClient#verifyTokenInternal (Network's deleted /internal/verify-token) and #getUserProfile (a route Network never had) are removed, and the deprecated openvibe-shared/chrome-ssr alias with them (use openvibe-shared/frame). Nothing in the estate used any of it. A test asserts the helpers stay gone. npm test 42/42.OpenVibers · 29 Sept 2026
47719cc -
Shared 1.30.0: pages never show unstyled (web-runtime inserts a fragment once its feature's and dependencies' stylesheets have loaded, all started together), rt.enter(section, work, { label }) hides a page until its route is ready, and route-transition.js (fetched on the first move) adds the top progress bar, a 'Loading …' line with the phase, and an opacity-only fade-in. Runtime docs moved to the README (6.2 KB brotli). npm test 42/42.OpenVibers · 29 Sept 2026
fabec42 -
Shared 1.29.2: navbar dropdowns (Live's Go Live → Dashboard) are no longer clipped by the sideways-scrolling links row: the menu is fixed-positioned under its link on hover, focus or tap, offset by a filtered bar's box. Usage notes moved from navbar.js to the README (navbar 28.7 KB brotli, budget 29). npm test 42/42.OpenVibers · 29 Sept 2026
e2c1bdf -
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 -
README and STATUS.json are current (roadmap WS-U task 3): the Charter's bold labels are now sections (Purpose, Owns, Does not own, Depends on, Capabilities, Acceptance), updated to the code (one package by ADR 0001, the Frame, web runtime and server helpers; jsonwebtoken the only runtime dependency; contracts v0.61.0 for tests), and the README gains Security (SECURITY.md, browser bundles, egress, trace, analytics, loopback metrics, immutable tags) and Deploy (a tag Network serves at /shared/* and sites pin) sections. The status line names v1.23.1 instead of v1.4.0 with an untagged 1.5.0 and drops the stale per-consumer pin list and CI note. STATUS.json gains deployed false, contracts and features and is updated 2026-09-28.OpenVibers · 28 Sept 2026
b5a9bd7 -
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 -
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.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 -
release-watch subscribes to topics=host.release.published (1.17.0, WS-P task 9)OpenVibers · 26 Sept 2026
3290dc5 -
release-watch: a CSP that leaves Events out of connect-src stops the release stream after one refusal (1.17.0, WS-P task 9)OpenVibers · 26 Sept 2026
2dfb257 -
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.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 -
openvibe-shared/config, the configuration model (WS-C task 7): createConfigStore keeps one namespace of a service's configuration as immutable revisions (common.config-snapshot@1) in the service's own better-sqlite3 database: get() from memory, JSON Schema subset and validate(), public/internal/secret classification, atomic activation with the last-known-good restored in memory and in the database when onActivate throws, rollback as a new revision, pruning that keeps the last-known-good, redacted history (a secret is an HMAC-SHA256 fingerprint under a random 32-byte key per namespace in config_keys, never served or logged; the checksum covers the values as shown), legacy import (fromRows) as revision 1; adminRoutes serves /api/admin/config (list, history, apply, rollback) with problem+json, on Express or plain http without depending on either; no new dependency (unreleased)OpenVibers · 26 Sept 2026
b473e0d -
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.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 -
1.6.0: openvibe-shared/egress, the one SSRF rule for Live, Events and Tools (strictest union of their drifted copies: 3fff::/20, 5f00::/16, NAT64 /48, Teredo; connect-time safeLookup, assertPublicUrl, EgressDenied), tested down to a refused socket; release.collect() keys beacons by req.ip (behind the proxy every socket was 127.0.0.1, one bucket for the whole site) or keyOf(req); STATUS versionOpenVibers · 24 Sept 2026
644d4c3 -
Track R (ADR-016, D42-D46): release manifests with components, open tabs updated in place, update metrics, and an N/N-1 mixed-version harnessOpenVibers · 23 Sept 2026
4b9e5d7 -
Shared ADR 0001 (proposed): one package with explicit subpath exports, not a split into @openvibe/* packagesOpenVibers · 23 Sept 2026
6f61fbc -
analytics: the ADR-021 module moves into Shared (register item 26, C-80); Sec-GPC/DNT requests are not recorded; analytics/event.v1 schemaOpenVibers · 23 Sept 2026
9aaf919