openvibers/openvibe.run Commits
OpenVibe.Run: the service skeleton and the job API (submit, read, list, cancel, stream ticket + SSE, admin) on the released run contracts (plan T14 R1a/R1b). (#1)
OP OpenVibers committed 7 Oct 2026 · tag v0.1.0 · 0 files, +0 −0
OpenVibe.Run is scaffolded and the R1b job API is implemented, tested and uncommitted (working tree only, HEAD still the empty `dc44223`).
## Files (34, none committed)
| File | What it is |
|---|---|
| `package.json` | Pins `openvibe-contracts` v0.106.0, `openvibe-sdk` v0.34.0, `openvibe-shared` v2.11.0 (codeload tarballs); `start`/`dev`/`test`/`test:pg` scripts, port 4920 |
| `package-lock.json` | Generated with `npm install --package-lock-only --ignore-scripts --no-audit --no-fund` (122 packages, correct tarball pins) |
| `server/config.js` | `loadConfig(env)`: PORT 4920, HOST/BASE_URL/TRUST_PROXY, DATABASE_*/VALKEY_*, OV_NETWORK_*, audience `openvibe.run`, events/oauth, `RUN_LIMITS_*` caps, the stream-ticket key, `RUN_BOT_URL`+`RUN_BOT_AUDIENCE`; **no Billing token** (Bot meters) |
| `server/db.js` | `openDb`/`migrate` on openvibe-sdk/db (pooled runtime role, owner role for migrations, PGlite in dev) |
| `server/network.js` | Network JWKS key provider + offline user-token verification (`openvibe-sdk/auth`) |
| `server/api/auth.js` | `req.principal` (service/user/anonymous), `requireCapability('run.job.…')` via `capabilities.check`, `requireProject` (403 `run.project_required`), requester/project from the token only |
| `server/api/v1.js` | The router: seven routes, one capability each, contract validation in and out, idempotency, keyset paging, cancel, ticket, SSE |
| `server/jobs/store.js` | `put/mint/get/list/adminList/cancel/mirror/settle/toJob/readResult/frameOf` over `run_jobs`; project-scoped get; the `job` record and the frame body |
| `server/jobs/events.js` | The six `run.job.*` emitters, outbox row keyed `run:<job id>:<state>` in the caller's transaction, payload validated per event contract |
| `server/jobs/stream.js` | Per-job ring + subscribers, monotonic `seq` as the SSE id, replay/Last-Event-ID, prune of idle/ended rings |
| `server/jobs/ticket.js` | Two-minute single-use RS256 compact JWS (audience `openvibe.run`, `typ run-stream`, Run's own key), jti consumed once |
| `server/events/outbox.js` | The openvibe-sdk service outbox (`run_events_outbox`, relay → Events, declared event types) |
| `server/dispatch/index.js` | **The T14 step 6 seam**: a no-op dispatcher (`place/cancel/poll/sweep/status`), jobs stay `queued` |
| `server/observability.js` | Truthful `/api/ready` (db required; valkey/JWKS/Events/Bot reported or skipped) + gauges |
| `server/app.js` | App factory: helmet, rate limit (problem+json 429), `express.json({limit:'768kb'})`, health/ready/release.json, loopback-only `/metrics`, problem+json 404/error handling |
| `server/index.js` | `main()`: migrate, listen, start keys/tickets/relay/dispatcher, `gracefulStop` (nothing starts at module load) |
| `server/util.js` | `RunError`/`fail`, time, job-id check, input errors, keyset cursor, requirements default |
| `migrations/0001_jobs.sql` | `run_jobs` + `run_events_outbox`, verbatim from the dossier |
| `test/jobs.test.js` | 21 checks: the job API against the released contracts |
| `test/app.test.js` | 9 checks: health, readiness, release.json, /metrics, the dispatcher seam, prod-no-key |
| `test/helpers/app.js` | Boots Run on a random port against an in-process Network stub (real RS256 JWKS path), SSE client, outbox reader |
| `test/helpers/db.js` | Migrated PGlite (or the containers with `RUN_TEST_STORE=pg`) |
| `test/run.js` | `openvibe-shared/test-runner` launcher, `parallel: 1` |
| `STATUS.json` | Repository/stage/wave/port/domain/contracts/capabilities
This commit has no diff to show.