openvibers/openvibe.run CHANGELOG.md
CHANGELOG.md
Changelog
Notable changes to OpenVibe.Run. The service is unreleased; everything below is 0.1.0 in progress.
Unreleased
Added
- The Arena's race on the one engine (compare-arena-ecosystem.md §3, contracts 0.422.0): the
raceplay as
agents.play@1(one role per side, one parallel phase, an even budget split,blind: true, stop on person), listed
byGET /api/v1/plays;POST /api/v1/racesstarts one childlinuxjob per side (2–4) under one parent race with
the same share of the budget each and answers the sides labelleda, b, …without names;GET /api/v1/races/:id
returns each side's output so far and its receipts when ended, the names only after a judgement;
POST /api/v1/races/:id/judgementrecords onebench.match@1on Bench (sourcearena, shown order,blind: true,
the receipts, ahuman_pairwisejudgement with an HMAC of the person) before revealing the names. Only the person
who started the race, through the same first-party service, may read or judge it.matchmaker: truepicks two
entrants of different model families fromRUN_RACE_ENTRANTSwhile Bench has no matchmaker endpoint. Migration
0020 addsrun_races. The race request/answer has no released contract yet, so it is validated in
server/races/service.js; everything it stores or sends is validated where a contract exists. - With
RUN_SESSION_ORIGINS_ENABLED=1, a browser session may name exact HTTP(S) origins at creation. Run stores the
list with the session, places it on a user-owned desk that can enforce the boundary, and sends the same list when
leasing that desk. Commands cannot replace the list. The switch is off by default.
- One Computer (plan 2026-11-07, contracts 0.327.0):
run.session@1carriestask_id(the OpenVibe.Actor task the
session is the Computer of, so the session points back at the task) andcurtain(the privacy screen).
GET /api/v1/sessions/{id}/stillanswers the desk's newest frame as a small JPEG (at most 640 px wide, cached for a
second so it captures at most once a second) from the desk's own capture on the session's lease; it is the session
person's alone, a signed-out visitor gets 404 like a missing session,Cache-Controlisprivate, no-store, and
whilePOST /api/v1/sessions/{id}/curtainholds it up the answer is the curtain picture, never the screen.
Migration 0008 addstask_idandcurtain. - Placement A1 (openvibe-sdk 0.76.0):
server/dispatch/placement.jscallsplace()— Bench priors (an hour's
cache), the person's learned counts and one plain line — and the same answer is stored on the job.GET /api/v1/jobs/:id?explain=1answers the line beside the contract body.placement_outcomes(migration 0007) learns
one outcome per ended job: exit 0 is ok, a failure or a timeout is not; a cancelled job is not counted. - The repository skeleton (plan T14 step 4, R1a):
server/config.json port 4920,server/db.js,
server/app.js,server/index.js,server/observability.js(/api/health,/api/ready,/release.json,
loopback-only/metrics),server/api/auth.js,server/events/outbox.js,migrations/0001_jobs.sql
(run_jobs,run_events_outbox),STATUS.json, the nginx vhost and the systemd unit. - The job API (plan T14 step 5, R1b):
POST /api/v1/jobs(run.job.submit),GET /api/v1/jobs/:id
(run.job.read),GET /api/v1/jobs(run.job.list),POST /api/v1/jobs/:id/cancel(run.job.cancel),
POST /api/v1/jobs/:id/stream/ticketandGET /api/v1/jobs/:id/stream(run.job.stream) and
GET /api/v1/admin/jobs(run.job.admin) — each validated against its released contract, with the project and
the requester taken from the token alone. run.job.queued|started|succeeded|failed|cancelled|expiredthroughrun_events_outbox, written in the same
transaction as the state change, and the two-minute single-use stream ticket with the SSE stream (replay,
monotonicseq,Last-Event-ID).server/dispatch/index.js: the dispatcher-bridge seam (plan T14 step 6) as a no-op, so every job staysqueued.
- The dispatcher bridge to OpenVibe.Bot (plan T14 step 6, R1c) and placement (step 7, R3):
server/dispatch/bot.js
(the client —send/cancel/statewith Run's Network client-credentials token for audienceopenvibe.bot
holdingbot.job.dispatch, cached until 60 s before expiry),server/dispatch/placement.js(the Fabric offers
plusopenvibe-sdk/placementplan(), withuser-ownedeligible only when the job's requirements name it) and
server/jobs/poller.js(RUN_POLL_MS, default 1000 ms): the ttl sweep, the send, the mirror of Bot's state with
onerun.job.*event per state change, the node's stdout as streamoutputevents, and the job_cancel. GET /api/v1/jobs/:id/streamalso opens with a Bearer service token holdingrun.job.streamfor the job's
project, beside the ticket.- The managed-browser provider adapter (plan T14 R4a,
server/dispatch/browser-provider.js): classbrowserjobs
placed on akind=provideroffer namedbrowser-providerare sent to the provider's API
(browser-provider.job-create-request@1, the frame alone: no project, subject or requester), mirrored, cancelled
and expired there; every answer is validated againstjob-create-result@1/job-state@1and a malformed one is
never adopted. Configured byRUN_BROWSER_PROVIDER_URL,RUN_BROWSER_PROVIDER_API_KEY(Run's env only, never
logged) andRUN_BROWSER_PROVIDER_TIMEOUT_MS(8000); off while the URL or the key is unset. - Run's own metering of those jobs: the provider's claimed wall time is clamped to Run's observed duration + 5 s
(a larger claim is logged and never billed), queued asplatform.usage-sample@1readings inrun_usage_outbox
(migrations/0003_usage_outbox.sql) with the end state, and relayed to Billing (RUN_BILLING_URL) with a Run
token for audienceopenvibe.billingholdingbilling.usage.record— used for nothing else.
Changed
- Cancelling a
placedjob no longer settles it at once: a job Run has handed to Bot is markedcancel_requested,
Bot is asked forjob_canceland the job ends when Bot reports it — Run never sayscancelledfor work a node may
still be doing. Aqueuedjob (sent nowhere) is still cancelled at once. POST /api/v1/jobsno longer places eagerly: the poller sends each queued job, so a submit never waits on Network
or Bot and a job whose lifetime ran out is never sent.RUN_JOBS_INTERVAL_MS/RUN_DISPATCH_INTERVAL_MSare replaced byRUN_POLL_MS(the poller's own interval).usage.wall_ms/usage.secondsare Bot's metered wall clock: 0 until the job'sjob_exit(Bot is the meter).
Notes
- OpenVibe.Bot owns the node link and the per-second metering of the jobs it carries (plan T14 L1); Run's Billing
token is for the external provider's jobs only. - The repo is not deployed; the first deploy needs
ovhost's inventory, theov_rundatabase,
/etc/openvibe/run.envandopenvibe.runDNS (see STATUS.json).