Commits
-
T2 Network on PostgreSQL, work in progress: what eight DeepSeek attempts left in the working tree (asyncified call sites, dialect fixes, migrations 0003-0006, test fixes); unfinished, continued on this branch by a cloud session.OpenVibers · 29 Sept 2026
206ab360 -
Network on PostgreSQL, the foundation (plan T2): openvibe-sdk v0.25.1 with pg, iovalkey and PGlite; migrations 0001_core (69 tables generated from the booted SQLite schema: identities, text timestamps via ov_now(), case-insensitive usernames by a unique lower(username) index, triggers in PL/pgSQL, boot seeds left to the code) and 0002_analytics; DATABASE_URL/DATABASE_DIRECT_URL/PGLITE_DIR/VALKEY_URL config; scripts/migrate-to-postgres.js (import with per-table count and checksum, --pglite dry run) and scripts/pg-preflight-collisions.js; the per-process migrated test database runner (not wired into npm test until the code is converted). Additive: the service still runs on SQLite and npm test is unchanged.OpenVibers · 29 Sept 2026
c114c402 -
The network's front door (plan T11, D93): the home page starts from what you came to do. A search box ('What do you want to do?') lights the intent it names and opens it, anything else is a tool search (the form's own action, so it works without JavaScript); eight intents are real links to where each thing starts (go live from a browser tab with no OBS and no follower minimum, tools, chat, a paste, play, write, the wiki, build on OpenVibe); the open sites form a constellation around you, the ones opening next faint on the outer ring. 'Right now on OpenVibe' shows who is live (with their current frame, falling back to the avatar), the newest public pastes and the newest posts, read from each service's public API over loopback, cached a minute, never delaying the page, with an honest empty state. The CSP allows openvibe.live thumbnails. test/home-front-door.test.js; the SSRF ratchet reviews the new call site; home budgets unchanged and green.OpenVibers · 29 Sept 2026
20dd7ff0 -
Grants for plan T3 and T4, on Contracts 0.80.0: Live reads a channel's moderation settings, moderators and emote count from Chat (chat.moderation.read); Chat uploads and deletes emote images in Media's chat namespace and runs the chat-AI summaries with its own token (ai.run.create/read, chat.*); Live reads, lists, uploads and deletes its objects in Media's live namespace and OpenRe uploads there, so both drop Media API keys. principals.test.js pins Live's Media scope. npm test green.OpenVibers · 29 Sept 2026
b5d87073 -
Plan T2 deletions in Network (each proven uncalled across the estate first): the one-time scripts hash-refresh-tokens, follows-backfill and creator-analytics-backfill; the built-in fallback tool catalog (before Tools has answered, the catalog is empty); the legacy OIDC alias /oauth/.well-known/openid-configuration (the issuer-root discovery and RFC 8414 stay); docs/patches; the Wave 0 roadmap baseline (scripts, docs, test), superseded by the plan; every README/docs mention of the retired X-Internal-Key (docs/retirement.md now records its retirement). Kept, with their callers: scripts/import-blocks.js (Chat's DM-blocks migration runs it) and scripts/secrets-out-of-db.js (no record that it ran). With an empty catalog the home page says 'Tools that just open' and 'free online tools' instead of '0', shows no empty rows, and llms.txt leaves the empty section out (test/home-empty-catalog.test.js). npm test green.OpenVibers · 29 Sept 2026
f6fe8570 -
X-Internal-Key is gone from Network (plan T2, the last step of the sweep): every /internal route takes only a service token with the capability it performs (the router gate answers 401 token.missing without a Bearer and keeps the exact-spelling rule); principals.guard has no legacy option and principal_usage records service tokens only; the URL registry read takes network.registry.read and the coin totals network.coins.read. Network's calls to Live, Media and Tools carry only its self-signed token (all three accept it: Live 66f590b, Media 8364eee, Tools 55e4b84). config.internalKey and the setup warning are deleted. Tests: the retired key is refused on every route that took it, deleted routes are gone rather than locked, a Games token keeps the ownership coverage the key gave. npm test green (verified).OpenVibers · 29 Sept 2026
3bff1360 -
X-Internal-Key retirement, Network's step (plan T2, register C-50–C-58), on openvibe-contracts v0.79.0 (via v0.78.0: the realtime manifest is gone, so the registry tests assert its absence). The 13 key-only internal routes nothing in the estate calls are deleted (verify-token, users/:id, users/by-username, users/bulk, users/:id/theme, users/:id/linked-accounts, audit, stats, notifications/unread/:userId, notifications/resolve-users, issue-token, anon-admin, anon-list). The two Live still called with the key take its token: POST /internal/user-avatar (network.avatar.write) and POST /internal/notifications/mark-read (network.notifications.push); Live is granted network.avatar.write, network.registry.read and network.coins.read. Network's own calls carry its self-signed service token (identity/self-token.js, one cache per audience and capability set): the avatar push to Live (live.avatar.write), avatar import on Media (media.avatar.ingest), Live's analytics totals (live.analytics.read), Live's registry refresh (live.url_registry.refresh), the Tools analytics (tools.analytics.read); the key rides along only while those receivers move. Games and Media never had /api/internal/analytics: the dashboard uses the navbar page-view count for them without asking. npm test green.OpenVibers · 29 Sept 2026
79a4eea2 -
openvibe-shared v1.29.2 (from its earlier pin): navbar dropdowns are no longer clipped by the links row, changing the theme repaints the page background, bright accents get dark button text (WCAG), the navbar brand is more compact. npm test: deploy wrapper: all checks passedOpenVibers · 29 Sept 2026
5ca28e2d -
openvibe-shared v1.29.1 (from its earlier pin): changing the theme repaints the page background, bright accents get dark button text (WCAG), the navbar brand is more compact. Account page: primary buttons use the theme's on-accent colour, the theme switcher applies through the shared loader (canvas and browser UI follow), and every text field follows the theme (input colour, hover tint, accent focus ring, placeholder, invalid state); the theme submission form uses the page's field style with a hint. npm test: deploy wrapper: all checks passedOpenVibers · 29 Sept 2026
60f5ab2b -
openvibe-shared v1.28.1 (from its earlier pin): the account panel keeps its sections' height on phones, the codes mark at rest shows its V, no empty space under the footer on phones. Images may come from openvibe.media (img-src): avatars and media live there, and the Network site's own CSP blocked them. npm test: deploy wrapper: all checks passedOpenVibers · 28 Sept 2026
768e0856 -
Operator alerts page once per episode and stop piling up (the bell had Alert/Resolved pairs every few hours). An opened alert creates one notification per operator; a critical one is pushed, a warning stays in the bell (create() takes silent). When it resolves, the same notifications are revised in place to Resolved, marked read, with how long it fired, instead of a new entry. One that fires again within 12 hours of resolving revises them back (Fired again n time(s)) and creates or pushes nothing. Only critical alerts get the 24-hour reminder, and info alerts are listed, never notified. The notification service gains revise(id, userId, fields); operator_alerts gains notices and reopened. Deploy drift: main ahead by documentation and tests only (README, STATUS.json, docs/*.md, tests, .github/: the files the deploy controller skips) is current, not drift.OpenVibers · 28 Sept 2026
35233db1 -
The node registry (roadmap WS-X1 step 3, ADR-034 §12; Contracts v0.76.0 network.node@1). POST /internal/nodes/report takes Host's token only (network.node.report, granted to host; no shared key) and network.node-report-request@1: it upserts every node of that source and marks the source's nodes missing from the report down, never deleting them. GET /api/v1/nodes is public (CORS *, max-age 60) and filterable by ?role= and ?region=, answering network.node-list-result@1; it is what openvibe-sdk/geo reads. GET /api/v1/nodes/:id/beacon is a no-store 204 with Timing-Allow-Origin for browser distance timing. The contract has no address field, so nothing private is stored. openvibe-contracts pinned at v0.76.0. test/nodes.test.js covers who may report, the contract, down-marking per source, the filters and the beacon.OpenVibers · 28 Sept 2026
719a00d2 -
OpenID Connect: an email claim that is a no-reply alias (roadmap WS-X12). Clients that need an address per account, first git.openvibe.codes (Forgejo, signed in with OpenVibe accounts), now get email = <subject>@noreply.openvibe.network with email_verified true, in the id_token and userinfo. It is built from the stable subject id, so it survives a rename, receives nothing, and never reveals the person's real address. Discovery lists the email scope and claims. test/oidc-discovery.test.js checks the alias and that no real address leaks. npm test passes.OpenVibers · 28 Sept 2026
795021a2 -
Roadmap baseline regenerated 2026-09-28 05:21 UTC after the no-fake-green rollout: 639 tables, 2453 routes, 112 call sites, 359 discrepancies, 6/7 exit criteria (EC7 waits for the host owner's hazard review). EC5 is now computed (nothing unobserved this run). Deploy drift: every service runs origin/main except Network's own baseline script change (2c1dacb, not part of the service); 4 more are behind only in documentation and tests. Every service pins openvibe-shared v1.25.0 and runs it.OpenVibers · 28 Sept 2026
13b7891f -
Roadmap baseline: no fake green (roadmap WS-Q task 7). EC5, "Unknowns are marked unknown, not guessed", was hard-coded to pass. It is now computed: the run lists what it could not observe (no production snapshot, a repository with no checkout under the scan root, a hazard check it could not evaluate) independently of the rows that record it, and passes only when each has an unknown discrepancy. Two gaps it found are closed. A repository with no checkout dropped out of every count silently; it now has an unknown checkout row. A hazard check that could not be evaluated rendered "-"; it is now an unknown hazard row and shows "unknown (not evaluated)". Without a production snapshot the checks that read production guessed ("socket unit not found", "NOT set", "every service runs origin/main", dead databases "none"); they now answer not evaluated. The deploy.drift metric separates services behind in what runs from those behind only in documentation and tests. Checked with and without prod-snapshot.json (9 things not observed, each marked unknown); test/roadmap-baseline.test.js passes.OpenVibers · 28 Sept 2026
2c1dacbe -
No fake green in Network's readiness and in the registry's status (roadmap WS-Q task 7; Shared v1.24.0). Production's /api/ready reported the Discord bot check "ok" with the detail "not configured"; it now returns skip('not configured'), so it reads skipped with its reason and never ok (an optional skip leaves the verified service ready). The registry (/api/v1/status, the registry's runtime rows) called three things "up" that verified nothing: a readiness body not in the openvibe-shared/ready shape (OpenRe's, basis ready-legacy: HTTP 200 alone), a liveness-only answer (basis health), and a shared-shape body whose checks all skipped or that had none. Each is now degraded with the reason; up needs a shared-shape body that says ready, degrades nothing and has at least one check with status ok, whatever Shared version wrote it. The row's ready summary keeps a skipped check as skipped (with its reason) instead of fail, and lists skipped. openvibe-shared is pinned at v1.24.0 (from v1.22.0). Tests: observability (no bot token: skipped, still ready), status (liveness only and the ad-hoc body are degraded; skip beside a pass stays up; all skipped or none is degraded), registry-ecosystem (its stand-in service now answers a real readiness body). npm test passes.OpenVibers · 28 Sept 2026
ac71bb4d -
Network notifies a new follow itself (roadmap WS-E task 3, D08: Live's pushes that have a domain event move off Live; ADR-020, ADR-030). Since follows moved to Network (FOLLOWS_AUTHORITY=network, 2026-09-26), a follow made on my.openvibe.network, another product or the API told nobody, and one made on Live was pushed by Live over the internal notification route. setFollow now calls a notifier (follows.setNotifier, set at boot to server/notifications/follow-notify.js) when a follow starts, inside its transaction, so the follow, its network.follow.created event, the FOLLOW notification and its network.notification.created event commit together; a notifier that throws is logged and never fails the follow. Flag changes, the same follow again, unfollows and imports (emit: false) notify nobody. The notification matches Live's (New Follower, "<name> followed you", the follower's channel at openvibe.live/@<username>, service live, the follower as sender) and goes through the notification service, so the social preference, blocks (actor_subject) and push apply. FOLLOW now shares the go-live dedupe: one an hour per sender, so unfollowing and following again does not notify twice (and Live's push, which names the same Network sender, is absorbed until Live stops sending it). test/follow-notify.test.js covers all of that; blocks.test.js's "unblocked" check uses a MENTION, since a second FOLLOW from the same person within the hour is now deduped. npm test passes.OpenVibers · 28 Sept 2026
8188c26f -
Roadmap baseline reads the release layout, and ranks docs-only deploy drift low. collect-prod.sh took every /opt/openvibe.<svc> checkout's HEAD, so Live, which runs from current -> releases/<time>-<sha> (a git worktree of repo/) since 2026-09-27, showed the pre-release checkout 9f7f36c as deployed and 120 commits behind; a service with a current link now reports that release's commit (layout: release, release name), and Live reads b0cc2ef, what /release.json says. generate.js still reports every service behind origin/main, but when the commits between change only documentation and tests (README.md, STATUS.json, docs/*.md, the baseline's own files, test/, .github/, *.test.*) the row is low and names the files, since those ride the next deploy; drift in anything that runs stays medium. Regenerated 2026-09-28 03:40 UTC: 639 tables, 2453 routes, 112 call sites, 377 discrepancies, 6/7 exit criteria (EC7 waits for the host owner's hazard review); the 24 deploy rows are all low (the README/STATUS refreshes and Live's re-recorded N-1 fixtures), and Codes, deployed at 64d8feb (C-61), is current.OpenVibers · 28 Sept 2026
0b1dbdff -
Roadmap baseline regenerated 2026-09-28 (roadmap WS-Q task 6): 639 tables, 2453 routes, 112 call sites, 378 discrepancies, from fresh production, GitHub and origin/main scans. 6/7 exit criteria pass; EC7 waits for the host owner's hazard review. Ownership rules for Live's four new bookkeeping tables: account_data_events (ADR-033), subject_merges (ADR-029), follow_projection_revisions (ADR-030) and lineage_unresolved. D39 (Mods) records mod principals in Network, enforced budgets, the security tests and the production lifecycle proof of 2026-09-27; only executable runtimes remain (Host Stage C).OpenVibers · 28 Sept 2026
c022f862 -
README and STATUS.json are current (roadmap WS-U task 3): the README gains Purpose (the opening sentence), Owns, Does not own, Depends on, Capabilities (the 20 capabilities in the manifest, where other services' grants are seeded, and the svc:network tokens Network signs for Events and AI), Acceptance (what the 74 test files cover) and Security (SECURITY.md, tokens, redirects, private data, CORS, secrets by name) sections; Deploying adds the unit, port, env file, rollback and the two schema blockers. STATUS.json is new, in the shape of Search's, updated 2026-09-28.OpenVibers · 28 Sept 2026
5a50c12a -
Per-actor limits on the account API's writes (roadmap WS-R task 4; openvibe-sdk 0.11.0 -> 0.12.0 openvibe-sdk/limits). server/auth/actor-limits.js counts writes by the person whose session token makes them (their subject).OpenVibers · 28 Sept 2026
ddd87b68 -
The admin AI panel follows Live's move to OpenVibe.AI (roadmap WS-O task 2, Live 04cd59f): the provider, key, base URL, model and price settings are gone from its list and its help text, and the status line shows which service runs AI instead of the removed provider, model and key fields (it read has_key as undefined).OpenVibers · 28 Sept 2026
6a686fe8 -
Live may cap a streamer's AI-viewer spend as an AI quota on their attribution (ai.quota.attribution.manage on openvibe.ai; roadmap WS-O task 2, AI 960f14a; openvibe-contracts 0.73.0 -> 0.75.0). test/principals.test.js follows Live's AI caps. npm test passes.OpenVibers · 28 Sept 2026
728266be -
Live may store a streamer's own provider key in OpenVibe.AI (ai.credential.manage on openvibe.ai; roadmap WS-O task 2, AI fca04c7; openvibe-contracts 0.72.0 -> 0.73.0), so Live stops keeping third-party keys in its database. test/principals.test.js follows Live's AI caps. npm test passes.OpenVibers · 28 Sept 2026
d37ee87f -
The probe principal may manage Games mods (games.mod.manage on openvibe.games) for the production mod lifecycle proof (roadmap WS-M task 6; Games apps/server/scripts/modLifecycleProof.ts installs, grants, uses and revokes a proof mod through Games' staff API). npm test passes.OpenVibers · 27 Sept 2026
2e9b5d54 -
Mod principals (roadmap WS-M task 3, ADR-013; openvibe-contracts 0.71.0 -> 0.72.0). server/identity/mod-principals.js: a mod install is the principal mod:<mod_id>, whose grants are the approved subset of what its manifest requests.OpenVibers · 27 Sept 2026
c3a64415 -
Account export and deletion (roadmap WS-B task 7, ADR-033; openvibe-contracts 0.70.0 -> 0.71.0). server/identity/account-data.js.OpenVibers · 27 Sept 2026
e2787eb4 -
A merged account has no tokens of its own (ADR-029, found in the first production merge). Revocation has second precision, so the folded-in account's fresh sign-in token, minted in the same second as the merge, still answered /me for up to an hour. verifySession now refuses any token of an account with merged_into (401 Account merged), and a merge revokes strictly: token_valid_after is one second ahead, so other services, which compare iat with the announced valid_after, refuse a same-second token too (revokeTokens gains strict). test/account-merge.test.js: a token minted in the merge's second is refused.OpenVibers · 27 Sept 2026
25226d22 -
Account merge (roadmap WS-B task 5, ADR-029; openvibe-contracts 0.68.0 -> 0.70.0). server/identity/account-merge.js folds a second account into the one a person keeps. The person: the account they keep opens a 10-minute intent (POST /api/v1/account/merge/intents); then, freshly signed in to the other account (auth_time within 10 minutes: a real sign-in, never a renewal), POST /api/v1/account/merge { intent }. Staff, for account recovery: POST /api/admin/account-merges { from, into, reason }, which needs staff.identity.merge (the owner), a written reason and an audit row. One transaction moves what Network owns: linked providers (a clashing one stays on the folded account and still signs in to the survivor), sessions, OAuth tokens and codes, developer projects and memberships, OpenCoins (debit and credit with reason account_merge, idempotent by merge id), user modules (the survivor's fields win; the other fills only what it lacks, network.module.updated subject_merged), follows both ways (a clash or a self-follow is dropped), blocks, notifications, preferences, push subscriptions and effects. It writes the alias (subject_aliases, kept flat), marks the folded account merged_into, revokes its tokens (network.user.token_valid_after, reason account_merged) and queues network.subject.merged. A retry answers the first merge. subjects.resolve answers the survivor, with merged_from, for the alias and any legacy id mapped to it (the legacy map is never repointed). Password sign-in to a folded account signs in to the survivor. Merge records drop their pre-merge state after 30 days (a daily reduce). User session tokens carry auth_time (OIDC): set at sign-in, and every renewal (requireAuth, refresh, OAuth authorize, themes, add-account sessions, the upstream re-mint) keeps the original or none; requireAuth exposes req.tokenClaims. my.html: a "Merge two accounts" card in Your Accounts runs the flow through Add another account. test/account-merge.test.js covers the ADR's acceptance tests (both sign-ins, resolution, coins once, module fill, moves and clashes, events, the folded token refused, sign-in lands on the survivor, staff reason and owner only, the 30-day reduction, auth_time on renewal). The module and staff-claims tests follow the field fill and staff map 1.2.0.OpenVibers · 27 Sept 2026
899ca7af -
Live's AI grants move to the new default at boot (follows d072928): CHANGED_DEFAULT_NAMESPACES moves Live's ai.run.create and ai.run.read rows for openvibe.ai from [live.*, network.site_copy] to [live.*, network.site_copy, media.analyze] when they are still exactly the old default (an edited row is left alone). A new default alone never reached the existing rows (seeded with INSERT OR IGNORE), so production kept refusing media.analyze. test/principals.test.js seeds the old default, boots again and checks Live's AI token.OpenVibers · 27 Sept 2026
9b3835db