openvibers/openvibe.contracts Commits

Run's manifest: its loopback origin, health and ready paths, and its real lifecycle (Network's status showed Run unknown) (0.214.0) (#216)

OP OpenVibers committed 19 days ago · aa9d7a1746 · 2 files, +40 −5

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex df575583..238082de 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -6,6 +6,10 @@ the notes were in the tag and commit messages (`git tag -n1`).
## 0.214.0 — 2026-10-26
++- **Run's manifest names its loopback origin** (`internalOrigin` http://127.0.0.1:4920, `health` /api/health, `ready`
++ /api/ready): Network's status page showed Run as unknown ("no internal address known to Network") although it runs.
++ Its `lifecycle` said "not built yet" throughout; it now says what Run does (shutdown drains, what it resumes at boot,
++ rollback, no leases).
- **Vibe by voice on a person's own machine** (the owner, 2026-10-24: "a call word on Live and on Node"; consumer plan
§8). `bot.device-message@1` gains two frames and two config fields, all additive:
- `voice_ask` (device to server): `id` and `text`, what the person asked after the machine's call word, transcribed
ddiff --git a/manifests/services/run.json b/manifests/services/run.json
iindex dd123968..38c1f4f3 100644
---- a/manifests/services/run.json
++++ b/manifests/services/run.json
@@@ -11,6 +11,9 @@
"openvibe.run"
],
"publicOrigin": "https://openvibe.run",
++ "internalOrigin": "http://127.0.0.1:4920",
++ "health": "/api/health",
++ "ready": "/api/ready",
"exposure": {
"state": "live",
"publicSite": "service",
@@@ -36,22 +39,50 @@
"namespacesOwned": [],
"lifecycle": {
"liveness": {
-- "none": "not built yet; nothing listens on a loopback address"
++ "endpoint": "/api/health",
++ "means": "the process is up and answers HTTP; the database, Events and Bot are what ready checks"
},
"shutdown": {
-- "none": "not built yet; nothing runs or drains"
++ "signal": "SIGTERM",
++ "deadlineSeconds": 5,
++ "drains": [
++ "Network key refresher stopped",
++ "stream tickets stopped",
++ "dispatcher poller stopped (no new tick; the one in flight finishes)",
++ "job event streams closed (a client reconnects)",
++ "events outbox relay stopped",
++ "HTTP server drained",
++ "telemetry flushed",
++ "store closed"
++ ]
},
"startupRecovery": {
-- "none": "not built yet; nothing starts"
++ "resumes": [
++ {
++ "kind": "state",
++ "what": "every job and its frames are committed rows: the first poller tick after boot places queued jobs, mirrors placed and running ones from Bot, and expires those past their ttl"
++ },
++ {
++ "kind": "outbox",
++ "what": "run.job.* events and usage readings written before the stop wait in their outboxes and are relayed at boot"
++ }
++ ]
},
"rollback": {
-- "none": "not built yet; nothing is released or rolled back"
++ "conditions": [
++ "automatic: ovhost deploy puts the previous sha back and restarts again when the ready URL does not answer 2xx within ready.timeoutSeconds after the restart (exit 3)",
++ "manual: ovhost rollback <service> --to <sha>"
++ ],
++ "window": "automatic only while ovhost waits for readiness after the restart; manual afterwards, as long as no blocker applies",
++ "blockers": {
++ "none": "migrations 0001-0004 are expand-only (Run's own job, usage outbox and telemetry tables): an older release runs on the newer schema"
++ }
},
"contracts": {
"range": ">=0.90.0 <1.0.0"
},
"leases": {
-- "none": "not built yet; nothing runs"
++ "none": "no claims: one process places jobs, one poller tick at a time; a job moves on by conditional row updates in Run's own database"
}
},
"notes": "The job service of the network (plan T14, ADR-034): accepts jobs (run.job-create-request@1), places each on a node that advertises worker:<class> (platform.resource-offer@1, platform.runtime-offer@1, platform.workload-requirements@1), sends it as platform.job@1 over the node link and follows its platform.job-frame@1 frames. Consumes billing.usage.record to write one usage reading per wall-clock second (run:<job id>:<n>, service run, operation function.invoke, unit s) and media.object.read to resolve digest-pinned inputs. Serves its job API on loopback :4920 (Run #1 and #2, 2026-10-07).",