openvibers/openvibe.contracts CHANGELOG.md
CHANGELOG.md
Changelog
0.423.0 — 2026-11-13
- Media lists
media.config.manageamong the capabilities it enforces: Media now serves its settings to the owner's
Setup at/internal/config(Media #441), so Network's setup and guide read it like every other service (the guide
said "OpenVibe.Media did not answer"). The capability itself has existed since the owner settings proxy.
0.422.0 — 2026-11-13
One evaluation loop: entrants, matches, and ratings that separate the model from the harness
(compare-arena-ecosystem.md). The owner, 11-13: the Arena "should still use our multi purpose shared universal agentic
multi harness system", and comparisons should do "harness vs harness and model vs model … better".
bench.entrant@1: what competes.- Kinds: a
model(on the neutral harness), aharness(over a fixed model panel), anagent(harness + model +
settings, a blueprint version), or aproduct. - Stable ids:
model:…,harness:…@version,agent:harness+model#confighash,product:…. bench.match@1: one task given to two or more entrants under the same budget.- Each side carries its receipts: cost, tokens, TTFT, TPS, wall time, tool calls, and the length and markdown style
covariates. shownrecords the order the sides were displayed in;blindrecords whether names were hidden.- Judgements come from
human_pairwise,audience_poll,implicit(merged, accepted, copied, kept, retried,
stopped, edited),test_suite,rubricandgame_outcome. A voter is a keyed hash with a quality weight, never
an id. - Sources: arena, chat, codes, live, games, exchange, space, bench and check jobs.
bench.rating@11.1.0 (all optional):entrant_kindandstyle_control;factors: an agent's strength split into model, harness and interaction, each with an interval;cost_per_solved_usd,tokens_per_task,ttft_msandtpspercentiles,reliability(pass^k),matches,
as_of.- Event
bench.match.recordedv1, produced by Bench. agents.play@11.1.0:blindhides the roles' names until the first judgement. This is the race play an Arena
round runs on the agent engine.- Fixtures:
- entrants: an agent, a harness, a model;
- matches: an Arena vote, and a Codes race judged by its tests and then merged;
- a rating with its factors;
- invalid: an agent without its harness, a kind nobody has, a one-sided match, an unknown judge.
0.421.0 — 2026-11-12
Every AI call, measured everywhere (ai-metrics.md).
ai.call.recorded@11.1.0 adds, all optional:operation(chat, completion, embedding, image, image edit, speech, transcription, translation, rerank,
moderation, decision, realtime, batch, tool);streamed, andtps(the decode speed after the first token);queue_ms;task,task_idandtask_ms, so cost and time add up per task;harness, andplace(provider, the person's machine, community, a plan, OpenVibe's hosts);error_class,fallbacksandcache_hit(an exact-cache answer);tool_callsandregion.ai.call-report@1: up to 100 calls a product made without OpenVibe.AI (Actor, Codes harness turns, Link's local
models through Bot, Vibe). They go to AI'sPOST /api/v1/usage/calls. AI prices any that bring no price, records
each once (by system + run or turn id) and publishesai.call.recorded@1. The capability isai.usage.report.report.ai-performance@1: how calls performed for one group (model, provider, operation, system, task, place,
harness):- success, fallback, streamed and cache-hit rates;
- TTFT, latency and tokens per second at p50, p90 and p95;
- tokens, charged and list cost, and cache savings;
- cost and time per task;
- the top errors.
Public answers group by model, provider or operation, with at least 20 calls.
0.420.0 — 2026-11-12
One agent system, measured. These contracts carry the decisions in one-system-v2.md, which come from reading 24
open agent projects.
agents.blueprint@11.1.0:rules.sandbox(read-only · workspace-write · full) andrules.network(none · public · listed domains): Codex's
three axes per run, next to the level that was already there.starters: one-tap first asks, Goose's activities.agents.permission-rule@1: a permission as data, from Gemini CLI and OpenCode.- It has an action (a tool, or a pattern), a resource, an effect (allow · ask · deny), and
when: attended,
unattended or any. - The last rule that matches wins.
- Unattended work never waits on an ask.
- The floor asks whatever a rule says.
agents.job@1: one job placed on a machine. Its kinds are check, review, build, eval, improve, desk and model.
It carries:- what it needs from the place, and its trust (public code only, or the owner's own machines);
- its budget, its placement with the reason, and its attempts;
- a result with a named exit and a link to the masked log.
Secrets never travel in a job.
agents.run@11.4.0:metrics, with:- the charged cost first (an estimate only where nothing was charged);
- tokens with cache reads and writes, latency and steps;
- a named exit;
- the checkable evidence of success (a test, a schema, a grader, a person, a Decision with its probability).
- Fixtures: a blueprint with sandbox, network and starters; three rules; a check placed on a shared node, and a
queued review; a run with metrics; and refusals for each.
0.419.1 — 2026-11-12
actor.agent.manage lists the blueprint routes Actor serves: the person's blueprints and the public gallery, one
version, the draft, publish, remix, the install screen, install, and an installed agent's version
(agents.blueprint@1, agents.install@1).
0.419.0 — 2026-11-12
Make your own agent: agents.blueprint@1. An agent anyone can read, change, share and run anywhere, as one small
document of ten parts:
- face (Design);
- brain (Exchange): auto, a size or one model; the ladder rungs it may use; the most it pays; an advisor;
Decisions; - knows: instructions with
{{inputs}}, skills, knowledge, and examples for Try it and Bench; - hands: each tool allowed or ask first, plus tool search. The tools are
ov:product tools,tools:apps,
connect:apps, the installer's ownmcp:servers,machine:files/shell/desk/browser/screen,robot:manifest
commands,harness:coding harnesses andagent:other agents; - places: none, own, shared, openvibe or sandbox, and what the work needs; never a machine by name;
- memory;
- rules: level, budget, who may ask;
- when: the Source kinds plus
eventandschedule; - makes: answers, an exact shape, and whether it is served to other agents over A2A or as an MCP tool;
- team: a play whose roles are other blueprints at fixed versions.
Inputs and needs sit above the parts. A blueprint carries no secret and grants nothing. A published version never
changes. Design note: agent-blueprints.md.
agents.install@1: a person's own agent, made from one blueprint version. It records the inputs they filled,
the asks they agreed to (by key) and the machines they chose. It says whether a version that asks for no more is
taken without asking, and holds apendingversion that waits for their yes.agents.run-start@11.2.0:blueprintruns a version once without installing it (Try it). Every tool asks
first.agents.run@11.3.0:agent.blueprint, the version a run's agent was made from.- Fixtures:
- five blueprints: Clip finder, Vibe as
bp_vibe, a draft with a grader team, a tool for other agents, a robot
driver; - ten refusals: full level without a budget, a tool nobody has, a schedule without a time, served as a tool
without a shape, a team role without a version, published without a date, a key in the brain, a machine by
name, an exact pick without a model, no instructions.
0.418.1 — 2026-11-12
LOOI's manifest, exactly as the P7 list says it, and not frozen until Maticus has checked it. The head has its own
delivery window (1–300 ms; 500 ms is its lifetime on the Live tray, head-only profiles use 300), the top-level
battery (0–100, polled) is a reading of its own, and p7_battery's unverified is listed as a field that comes only
with a read at connect or a stale value. bot.robot-manifest@1 readings take optional: the fields that come only
sometimes. 0.418.0 marked the example frozen before the maker's check; frozen is now false until he confirms it.
0.418.0 — 2026-11-12
A robot's own manifest: bot.robot-manifest@1 (public, ADR-043) is what a robot's driver says the robot can do,
written and versioned by the driver's maker, so a new control is a version bump of the manifest instead of an
OpenVibe release (the plan in Maticus's LOOI thread, 11-10; his P7 command list on 11-12 is its first frozen version).
- Commands: kind, class (
motion,state,action), the value's fields and ranges,lifetime_ms, the
delivery_mswindow Bot gives it,min_left_mson arrival,rate_per_s,release(stop,hold,none;
motion must stop or hold),latched, the telemetry key thatconfirms it, and thecontrolthe panel draws
(stick, slider, toggle, button, pad). An actuator names which one. - Telemetry: a key, its fields (ranges,
boolean,string,ms,integer,number, or a list of values),
unit and range,source(poll,push,connect),fresh_ms, and its control (meter, readout, badge, list). frozen: true once the maker and OpenVibe have checked a version against the driver's real command list.ui.surface@1parts say what they send or show: optionalcommandandreads, in the manifest's terms, so
OpenVibe AI knows a part's ranges, lifetime, release and rate when it arranges a panel or writes a control. They
grant nothing: the product's gate still checks every command. A new example is LOOI's panel built from its manifest.- Fixtures: LOOI 1.0.0 through the P7 tray (drive 500 ms life, delivery 1–300, release stop; head 500 ms, hold;
headlights delivery 1–250, 50 ms left, 2 a second, latched; battery by poll withatin ms; who is driving), and
three refusals (motion without a release, an actuator without its name, motion that is never released).
0.417.0 — 2026-11-12
The agent engine's next shapes: who asked, what a run continues, how several agents share one ask, and where the
money went (agent-engine.md §§3-5, from the code study). Every field is optional and the new contracts are new.
agents.run@11.2.0:mandate: an ask taken in from the feed, a room, an issue: where, by whom, explicit or inferred, and the scope;lineage: a fork, a hand-off or a regenerated turn, with the run and turn it came from;playandrole;agent.capabilities;cost.by: the spend on each rung of the ladder (machine, plan, key, allowance, credits).agents.step@11.2.0:turn.agents.run-start@11.1.0:play,lineage, andmandate(from intake only).- New
agents.play@1: a play as data, made of roles, phases, checks, a stop rule and a budget split. Fixtures:
advisor, grader loop, fan-out. - New
agents.source@1: one place asks are taken in: who may ask, what counts as an ask, the run it becomes, its
budget, and how the run answers. Fixtures: the owner's feed, Vibe in a room. - Stop is a plain control. On small hobby robots, the panel's Stop is one ordinary, optional control that sends
the machine's own halt: bot.robot@1: the description and the old latch field say it is legacy (always false); schemas are unchanged.bot.device-message@1: the old latch frame and theestop_*fields are described as legacy names devices may
still send, not as a remote latch; Bot's config always sends the latch false.bot.command-result@1,bot.robot-control-result@1,bot.robot-manage-result@1,bot.command.refused@1: the
old stop endpoint and refusal code are gone from the descriptions.bot.estop.set@1andbot.estop.cleared@1are retired (fixtures and schemas stay for the contract window).ui.surface@1: Stop is not a required part;ui.action@1names Stop alone;ui.trigger@1addsstop.- Manifests and ADRs use Stop;
bot.resource.controlstop sends halt and resume is a calm no-op.
0.416.0 — 2026-11-12
One view API for every content kind (the owner, 11-12): a preview in the feed and a watch on a page count the same
item once, and Report can say how many people watched and how many stayed.
- Add
media.view-request@1:POST /api/v1/views{ ref: { service, kind, id }, how: preview | watch | live, seconds,
of_seconds?, session } on OpenVibe.Media (batched by{ events: [ … ] }, at most 20), with the preview/engaged
thresholds and the 30-minute per-viewer window. - Add the
media.viewedandmedia.engagedevents: the counted view and the first engagement for an item, with the
optional Report dimensions site and creator and no IP, user agent or raw session id. - Fixtures for both events and the request, and the generated JSON Schema and TypeScript.
0.415.0 — 2026-11-12
One feed for all of OpenVibe: the card OpenVibe.Network serves from /api/v1/feed and /api/frame/feed, and that
OpenVibe.Community's Pulse reads instead of its own collector.
- Add
feed.item@1: each card's stable id, kind (post, pic, clip, video, live, stream, rundown, quest, member,
chat, event, wiki, update, work, deal, news, report, poll, game, meme, paste, episode, space, avatar, banner,
follow, site), link, source site, actor and subject, first picture, counts (views, likes, comments, watchers,
people), live_now, a folded group of the same kind, a report trend, starts_at and follower visibility. - Fixtures for every kind, plus invalid ones (unknown kind, missing id, a URL without a scheme, a negative count, a
subject that is not a usr_ id, private visibility, a one-item group, a trend without a direction), and the
generated JSON Schema and TypeScript. Additive and new: no existing contract changes.
0.414.0 — 2026-11-12
The whole run (the agent engine, docs/agents-runs.md; design agent-engine.md). The owner, 11-12, with the menu's
Chat · Code · Agents switch crossed out: "one new unified agent … the same agentic system, shared across agents, code
and chat". Everything a person asks an AI to do is one shape: a run, and its thread of steps.
agents.run@11.1.0, optional fields only:title,kind,ref(its address on the Frame),url;model,where,target;doing,waiting,preview,counts,ended_at;context,outputs,visibility;- the agent's face:
agent.glyph,agent.hue,agent.avatar_url,agent.harness. agents.step@11.1.0, optional fields only:from,author,status,title,glyph,attachments,sources,
ui(a rich card) anddesk.- Add
agents.run-start@1: what starts a run on any product and on the Frame. Onlytextis required. - Add
agents.event@1: a run's stream (run,step,delta,approval,end). - Add the event
agents.run.updated(@1): the run's snapshot on OpenVibe.Events when what a list draws changed. - A conversation is a run that is
waitingfor amessage; an approval and a takeover are the same status with
anotherfor.
0.413.0 — 2026-11-12
The composer's Reach (Post · Ask · Do, stage R3; Network R3): what its / and @ menus offer.
- Add
frame.commands@1:GET /api/frame/commands?site=<host>&q=on OpenVibe.Network, the command rows a composer
offers on one site — the network's/ask,/do,/remindand/timer, the site's own from its Frame manifest,
and a signed-in person's saved composer snippets — each with its hint, the text a pick inserts, its kind and whether
it needs a signed-in person. - Add
frame.mentions@1:GET /api/frame/mentions?q=&site=on OpenVibe.Network, at most eight rows for the@menu:
public people (with a handle, display name and an OpenVibe.Media avatar only), the person's own agents from the agent
directory, open OpenVibe sites and Live's public channels. People first; signed out, public people only; no email or
private account field. - Fixtures for both (valid and invalid) and the generated JSON Schema and TypeScript.
0.412.0 — 2026-11-12
One agent system, stage 2: one run shape for Actor, Codes and Run, and the step event that follows it.
- Add
agents.run@1: a run's id, owner, agent and product, parent run, budget (USD, tokens, seconds and steps),
status (planning,running,waiting,done,failed,stopped), created and updated times, a result summary
and what it spent. One shape for OpenVibe.Actor, OpenVibe.Codes and OpenVibe.Run. - Add
agents.step@1: one entry of a run's append-only log (run id, seq, kindthink|tool|message|approval|child|file,
text, the tool call and its input, the result, the step's cost, start and end, and the child run it started). - Add
agents.approval@1: an ask attached to a run's step (what, the options with their labels, who decided and when,
and the answer). - Add the event
agents.step.appended@1: the appended step as the payload, on OpenVibe.Events. Theagentsnamespace
is hyphen-free because an event type cannot carry a hyphen; Actor registers the producer. - Add valid and invalid fixtures for all four, the generated JSON Schema, TypeScript and per-service OpenAPI, and
docs/agents-runs.md: which field of Actor'stasks/task_eventsand Codes'run_tasks/codes_session_lines/
codes_approvalsbecomes which field of the new shape, and what does not fit (Actor'sneeds_you, per-step cost,
split tool call/result entries, and Codes' attempts as one flat run).
0.411.1 — 2026-11-12
- Add the
codecategory tosources.source@1,sources.item@1,sources.category@1andsources.source-write-request@1: GitHub repositories (trending, top, new and star-gain rankings) enter OpenVibe.Sources under one category, with a 30-day item window. Additive: no existing field changes, and an older reader ignores the new enum value.
0.411.0 — 2026-11-12
The composer's Frame (Post · Ask · Do; Network #858): what its Model sheet lists and what an Ask sends.
- Add
frame.choices@1:GET /api/frame/choices?task=on OpenVibe.Network, the models a composer offers for a task in
groups (OpenVibe's, the person's keys, computers and plans), each row with its maker, price per million tokens in and
out, speed, Report score and its Exchange page, plus the recommended and current choice. - Add
frame.ask@1: the body ofPOST /api/frame/ask, the question, the model (a row id or{ model, source, machine }),
the sources to search (web,openvibe,mine,page), the depth and the files and page context it carries. - Fixtures for both (valid and invalid) and the generated JSON Schema and TypeScript.
0.410.0 — 2026-11-11
A train of three pull requests: the layouts of make-your-own-controls (#455), Elements stage 1 (#456) and the deep dive
(#457).
- Add
ui.surface@1(the catalog of a surface's parts, their minimum sizes, styles, bindings and
never_coversrules),ui.layout@1(a person's arrangement on one device class, with its name, author and
sharing),ui.layout-request@1(catalog, current layout, words and device for the AI task) and
ui.layout-suggestion@1(a validated layout with a one-sentence summary, reasons and the model's receipt, or
an honest refusal with the validator's reasons). - Add
network.layout.changed@1: the event Network writes in the transaction that sets, saves, renames, deletes,
shares, publishes, copies or resets one person's layout. It carries the surface, device, layout id, change and
revision, never account data or layout contents. - Add
ai.layout.suggest(first-party,POST /api/v1/ui/layout/suggest) andnetwork.layout.read(first-party,
GET /api/v1/people/:subject/layouts/:surface), and list them in the AI and Network manifests. - The fixtures cover a bot-controls catalog, a phone layout, a docked overlay, a suggestion and a refusal, a
request and the event; the suite checks part ids, theme tokens, never_covers targets and the 44 px minimum. (#455) - Add
ui.element@1: a look from OpenVibe.Design's components and the theme's tokens, a recipe (triggers, conditions,
actions), the capabilities the element declares, an optional mod reference (id, version, digest) and its sharing.
The store assigns the id and revision; a draft has neither. - Add
ui.trigger@1(press, hold, double-press, key, gamepad, chat command and text, follow, tip, AI Moment, Rundown
topic, timer, schedule, robot telemetry and event, stream start and end, viewer count, another element's event) and
ui.action@1(robot, chat, screen, stream, AI, Actor, webhook and tip-goal actions), each action carrying the product
that authorises it.ui.action@1's$defs.capabilityis the one list an element'scapabilitiesdraws from. - Add
ui.element-state@1: the element's own store (counters, scores, lists), with a revision that grows per accepted
change and values that are booleans, numbers, short strings or lists of them, never objects. - Add
live.element.pressed@1andlive.element.state@1: a press with the presser's public name and the trigger, and
the store with its revision, written by Live. - Fixtures cover a gallery dance button, a chat counter, a mod element, trigger and action variants, the state, and
both events;test/elements.test.jsholds the capability list to the action catalog, each kind to its product, and
the recipe to the element's declared capabilities. (#456) - Add
ai.deep-dive@1: a deep dive run's report as OpenVibe.AI'sdesign.deep_diveworkflow produces it for
OpenVibe.Exchange and OpenVibe.Design — the question and depth, the seven steps, every source, every capture (a
private Media object per viewport and theme, with its DOM facts and Expert extras), the per-site analysis, the
synthesis, the recommendations checked against OpenVibe's rules, and the receipt. Every claim carries its evidence. - Add
ai.deep_dive.updated@1, the event AI writes on each step transition and at the end, so a page can follow a
run without polling and Design can attach a finished report. (#457)
0.409.0 — 2026-11-11
- Define machine access requests, grants and signed token claims; the agent directory, A2A tasks and results; five Network events and four registration and relay capabilities.
0.408.0 — 2026-11-11
The rest of the 0.407.0 train. v0.407.0 was tagged at #451's merge, before the train merged, so the tag holds #451
alone; a tag is never moved, so the three pull requests the train carried are released here.
- Add
codes.task-summary@1(a task as the Dock's Code tab lists it: id, title, status, mode, repo, times, attempts,
url, preview and PR links) andcodes.task.updated@1, the one event Codes writes on every task status change beside
the per-statecodes.task.*events (#425). - Add
compare.comparison@1: things, weighted criteria, finite results with required observation dates and HTTPS
sources, method, source list and update date; register the Compare service, repository and product in Read & ask
(its group gains an eighth tile) (#428). - Add the optional
is_testtoidentity.subject-projection@1so public surfaces can leave probe and test accounts out
while their own signed-in views keep working, and the{ subjects }answer of Network's
GET /internal/identity/test-subjectsinidentity.resolve-result@1(#450).
0.407.0 — 2026-11-11
- Add
exchange.search.icons: a first-party service searches icon references through the Exchange platform API (POST /v1/search/iconsatapi.openvibe.exchange, served by OpenVibe.AI) with its own free-search quota and no Exchange key. It reaches the icons route only, never web, image or fetch search, and the receipt names the engine, cost and skipped attempts. OpenVibe.Design holds it for the references shown beside a glyph draft. (#451)
0.406.0 — 2026-11-11
The second train of the day, for the five pull requests opened after 0.405.0 (one line each):
- Define
meme.caption.createdfor a signed-in person's public caption, with only its id and owner (#444). - Add
codes.model-plan@1: execution modes, role models and effort, bounded samples and budgets, an escalation ladder
and required checks; task requests accept a plan or a preset, and task reads can include the resolved plan and
per-role usage and outcome (#445). - Delivery and retry on computer and browser results:
bot.command-result@1andrun.session-control-result@1gain
delivery(delivered,not_delivered,uncertain) andretry(safe,reason), onlynot_deliveredis safe
to replay; optional browseroriginson browser commands, Run session creation and Bot desk lease creation (#446). - Add
ai.model-directory-entry@1andai.model-directory-list@1for public model listings, with provider-listed
models routed off, preview and retired models, and sourced pre-list sightings; a spotted entry never implies
availability (#447). - Keep the exact reply target and its display name in Community comment reads; document the two-reply preview and four
Chat-compatible file references on comment writes and reads (#448).
0.405.0 — 2026-11-11
This release train carries the contract work that was waiting on the owner's release. One line per carried pull request:
- Add
live.layout@1, the player layout a person keeps in their account: per stream slot and source, the place as fractions of the frame, modedockorfloat, the tuck side, mute and the time, at most 60 places (#442). - Add
chat.command-registration-request@1andchat.command-registration-result@1with the active capabilitychat.commands.register, so a consented app or an Actor agent can register a plain response command for a server its person manages (#441). - Catalog OpenVibe.Directory as a live service and site, replacing its parked product metadata, with its public origin, source refresh lifecycle and public-listings-only scope (#440).
- Add
actor.agent-sheet@1andcodes.agent-sheet@1: the owner-scoped agent sheet responses, with current work, daily activity, approvals, computer, schedules and memory where recorded (#439). - Extend
community.feed-item@1,community.pulse-item@1andcommunity.pulse-write-request@1with activity kinds, followers-only visibility, scheduled starts, previews and links to every item in a folded burst; Community consumes Network profile updates (#438). - Add
chat.person-memory-result@1andchat.person-memory-preferences-result@1: the public and private parts of Chat's compacted day, week and month memory, and the erase and opt-out responses (#437). - Add
preview_url(andpreview_webm_urlon media) tomedia.vod@1,media.clip@1and the Live stream shapes: the 6 s muted hover preview beside a thumbnail (#436). - Add
agent.ui-event@1with the AG-UI 1.0 event union and OpenVibemetadata.ov,agent.run@1snapshots, and theagent-runchat embed (#434). - Add
network.user-card@1with viewer-aware actions, andnetwork.user-report@1,network.user-report-request@1andnetwork.user-report-list-result@1for a person's reports and the staff queue (#433). - Add
community.feed-card@1andcommunity.feed-answer@1, with preview media support (#432). - Add
composer.attachment@1,composer.prefs@1andcomposer.mention@1, the shared composer's server-side shapes (#426).
Valid and invalid fixtures cover every new shape, and the generated TypeScript, JSON Schema bundle and per-service OpenAPI files are regenerated at this version.
0.404.0 — 2026-11-11
- Add owner-only Run compute configuration capability for Network admin proxy.
0.403.0 — 2026-11-11
- Extend
actor.task-create-request@1with conversation, tools, model and optional content tier fields for Actor turns; uncensored content is available only when a task names the person it is for. - Deprecate the account-merge contracts after removal of the feature across services; retain the released schemas.
- Add
chat.embed@1as the shared address preview shape for chat clients.
0.402.0 — 2026-11-11
- Activate
download.file.readfor grant-bound, per-file reads by agents on openvibe.download; the capability alone does not provide drive listing or access without an owner's active grant.
0.401.0 — 2026-11-11
- Add the
live.channel_points.readcapability (withlive.channel-points-page@1): OpenVibe.Network reads one channel's points moves for the person behind a Network account through Live's internal channel-points changes read, for the gain/loss API (ask 273).
0.400.0 — 2026-11-10
- Regroup the sites into the owner's eight groups (plan ask 274, 2026-11-10):
site.neighbourhoodis nowwatch,talk,play,read,shop,tools,makeorbuild, the same ids and order as OpenVibe.Networkframe/sites.jsGROUPS and OpenVibe.Sharedrooms.jsHOODS. Every site manifest carries its new group; merged sections point at the site that shows them (Media → Video/watch, Bench → Report/read, Play → Games/play).
0.399.0 — 2026-11-10
- #408: add
quest.today@1, the private Quest today response. - #412: extend
network.operator-alerts-request@1with browser-check evidence and release timing details. - #415: add the
git.checks.writecapability for reporting commit statuses. - #416: add
agent.finding@1for confirmed findings, leads that need validation and rejected claims.
0.398.0 — 2026-11-10
codes.task@2's outcome state names a goal task's honest end state:readyonly with an accepted independent verdict,waiting,blockedat its no-progress limit,failed,droppedby the person, orstopped_by_budget. A task without a goal keepsdone,unfinishedandstopped.
0.397.0 — 2026-11-10
- Add
agent.goal@1: a task's outcome in words, a typed check (command,urlorrubric), optional resource budgets (tokens, turns, active minutes) and a no-progress limit, plus the worker's bounded completion proposal and evidence and the independent verifier's verdict (accepted or rejected, with a reason and the check's own output). codes.task-start-request@1takes the optionalgoal;codes.task@2carries it back with the worker's proposal, evidence and the verifier's verdict.
0.396.0 — 2026-11-10
- Add optional ordered attempts to web and image search receipts, with provider/engine, status, safe reason codes, latency and cost. Existing receipts remain valid.
0.395.0 — 2026-11-10
- Add two planned products to the catalog:
manifests/products/openvibe.compare.json(OpenVibe.Compare: compare anything side by side with its sources and dates, AI models first) andmanifests/products/openvibe.directory.json(OpenVibe.Directory). Both arenoRepowith launch notes; the addresses are parked. Compare's "meanwhile" link is OpenVibe.Exchange, where the models and their prices live today.
0.394.0 — 2026-11-10
- Add
chat.room-insight-result@1(contracts/chat/room-insight-result.v1.json): the public answer ofGET /api/v1/rooms/:id/insighton OpenVibe.Chat. One shape for every room:overview(the text written for someone arriving now, its topics with message counts, how many people and messages the window held, its from/to times and when it was written),timeline(the room's notable moments, newest first, each withat,kind,title,textand themessage_idit came from), andstate(ready/quiet/off). Quiet is explicit: an old or empty summary carries no text rather than invented news. The overview reads only people who allowed AI use of their messages (network.consent@1, purposeai.trainon kindchat).
0.393.0 — 2026-11-10
billing.money-reason@1: declaredonation:received, the row a creator sees for a tip that arrived ("for a tip from @alice"). The kind list is one list; the sender'sdonationstill reads "for a tip to @bob".
0.392.0 — 2026-11-10
- Add
billing.money-reason@1andlib/money-reasons.js: one list of the plain words for a movement of OpenCoins, Vibes or Balance. Each kind declares the key it matches (quest:publish-a-video,Media request: <title>, Billing's type:metadata), its site, what its subject is (a quest, a stream, a tip, a creator, an app, a project, a purchase), the phrase that names it ("for the quest {name}"), and how the subject's own name and address are found.describe()answers{ key, text, subject: { name, url } | null }, so a page writes "+15 OpenCoins" before the text and links it; an undeclared key reads "for something on <site>" withknown: falseand never shows the key. Fixtures cover a quest, a tip, a reason with no page and an undeclared key.
0.391.0 — 2026-11-09
- One Network experience curve, named reasons, level reads and capped service awards.
0.390.0 — 2026-11-10
- A service manifest's
siteblock takes an optionalstrip: up to three items a site adds to the network's footer strip, read with the rest of it at OpenVibe.NetworkGET /api/frame/online?site=<id>. An item is a plain label, an icon from openvibe-shared's glyph set, an https link on anopenvibe.*domain, and either acountthe site reports or a fixedline— never both. Live, Community and Games declare one each as the worked examples.
0.389.0 — 2026-11-10
- Add
ai.advisor@1: how a run may ask a stronger model for advice during the run. Off when the request omits it; at most 3 uses and at most 100 words of advice; the advisor may be named, the effort is concrete, and each use is on the run's receipt with its cost. Addai.advice@1: one use on that receipt, naming the advice run, the model, the tokens and the cost.ai.run-request@1takes the optionaladvisorfield andai.run@1's explain carries the uses.
0.388.0 — 2026-11-10
- Add
git.clone-request@1: one "Clone to my computer" request from a repository page. Git mints it for the signed-in person, the person's Link reads it over an outbound HTTPS relay, asks for approval on the machine, clones into a folder inside the root the person chose in Link, and reports progress back; the page polls the same document. The request lasts two minutes, only a repository the person may read can be requested, andclone_url(with a short-lived read token) is present only in the Link's answer, never in the page's copy. - Add
git.machine@1: a computer published to OpenVibe.Git through Link, read-only. It lists the repositories under the root the person chose in Link, each with its branch, head commit and date, and whether the machine is online ("offline since …" when it is not). Browsing is asked of the machine over the poll it opened; nothing in this contract is a write path. - Valid and invalid fixtures cover a pending, cloning and done request, a bad id, a bad state and a traversing repository name, and an online and offline machine, a machine without repositories and a repository name that escapes its root.
0.387.0 — 2026-11-09
- Add
ai.creation@1andai.creation-list@1: the catalogue of everything AI can make on OpenVibe, one entry per creation. An entry names the product it lands in, a plain one-line name, what the person gives it and what comes back, the workflow or registered task behind it, who may use it (guest, signed-in, the 18+ floor), whether it can cost coins, and the URL where a person starts it.GET /api/v1/creationson OpenVibe.AI answers the list, built from the registered workflows and tasks so only what is live is listed; the contract is public and its fixtures show a workflow creation and a task creation.
0.386.0 — 2026-11-09
- Add
chat.command@1for registered slash commands and typed options.
0.385.0 — 2026-11-09
- Add
ai.file@1plus typed conversational turn request and result shapes for Media-backed attachments and artifacts.
0.384.0 — 2026-11-09
- Agent work fabric: trigger, decision, immutable ticket mandate and budget, six report states, attention, and ordered stage vocabulary. Portable AI effort, concrete task-default effort, and optional effort/ladder receipt metadata.
0.383.0 — 2026-11-09
ai.provider@1: measured per provider+model circuit health (status, failure class, plain reason and since when, retry/backoff, notify time);ai.run-read-result@1:requests[].error_class.
0.382.0 — 2026-11-09
- Add
exchange.market@1: paginated own-page market offers, routing flags and per-field model metadata provenance.
0.381.0 — 2026-11-09
- blog.changelog-entry@2: a shipped change with its plain words, kind (new, better, fixed or internal) and one to three areas from Blog's fixed list, with the commit and pull request for the row's fold
0.380.0 — 2026-11-09
- Exchange routing controls, owner request presets and generation accounting schemas, with valid and invalid fixtures.
0.379.0 — 2026-11-09
- Wiki's rich articles: the page write request and the page read result carry
blocks(publishing.block@1) next to the Markdown, andwiki.images-suggest-request@1/-result@1andwiki.article-draft-request@1/-result@1describe the image suggestions (wiki.article.images) and thecontent.wikidraft revision that waits for a person.
0.378.0 — 2026-11-09
- OpenVibe.Connect and the relay profile describe the Link, not the Node.
0.377.0 — 2026-11-09
- community.feed-item@1: live_now on a live stream's row
0.376.0 — 2026-11-09
- git.change@1, git.issue@1 and the review events for OpenVibe.Git's changes and issues (G2)
0.375.0 — 2026-11-09
- AI tasks and choices:
ai.task@1,ai.choice@1,ai.task-defaults@1; a run acceptstaskorchoicebesideworkflow, andrun.explain.task_choicesays what answered.ai.me-preferences@1gainsdefaults.search.
0.374.0 — 2026-11-09
- Add the Pics public gallery and picture contracts (
pics.gallery@1,pics.picture@1) with valid and invalid fixtures.
0.373.0 — 2026-11-09
- The git service: its manifest, git.repo.read and git.repo.write, git.access-request@1 and git.access-result@1 (OpenVibe.Git)
0.372.0 — 2026-11-09
- The machine product Node became OpenVibe Link. The network registry contracts are
network.link@1,
network.link-report-request@1andnetwork.link-list-result@1, the event isnetwork.link.revoked, and the platform
carriesplatform.link-capabilities@1andlink.compute@1. The capabilitiesnetwork.node.manage,
network.node.reportandnetwork.node.self.managearenetwork.link.manage,network.link.reportand
network.link.self.manage; their internal routes and the manifests follow. - A paired machine is a
linkprincipal: identity.service-token-claims actor_typenodeislinkwith sublink:lnk_…,
andids.principalSubmintslink:lnk_…(the old prefix and ids are gone, no alias). The AI providernodeislink
in ai.credential-put@1/@2 and ai.credential@1/@2. The old contract ids are deprecated with their Link replacements; the
schema corrections are recorded against the current release and the ones before it.
0.371.0 — 2026-11-09
- Exchange API platform and search: exchange.key@1, exchange.key-created@1, exchange.usage@1, exchange.deployments@1, exchange.search-result@1, exchange.image-result@1, and the Exchange manifest's routes
0.370.0 — 2026-11-09
- design.component@1: one platform-neutral definition per shared interface (the public registry on openvibe.design)
0.369.0 — 2026-11-09
- OpenVibe Git: git.repo@1, git.commit@1, git.tree@1 and git.insights@1
0.368.0 — 2026-11-09
- The wallet and the reviewed store: billing.wallet@1, inventory.store@1, inventory.store-listing@1, inventory.purchase@1
0.367.0 — 2026-11-09
- publishing.block@1: the rich content block of a post or an article body
0.366.0 — 2026-11-09
- wiki.page.published@1 and wiki.page.updated@1 carry an optional
title(the page as readers see it), so the network's Feed names a wiki page by its title, not its slug.
0.365.0 — 2026-11-09
- Dock v2: action-item words, ai.run-error@1, skill runs and Vibe conversations
0.364.0 — 2026-11-09
- The Feed of everything: community.feed-item@1
0.363.0 — 2026-11-09
- npm metadata and CITATION
0.362.0 — 2026-11-09
- Your stats: report.me-stats@1 and report.me-stats-publish@1
0.361.0 — 2026-11-09
- Reviewed glyph draft service
0.360.0 — 2026-11-09
- Meme entry and render contracts
0.359.0 — 2026-11-09
- Media multipart uploads in contracts and OpenAPI
- Define
design.component@1for web, Android and iOS component anatomy, props, states, tokens, behavior, accessibility and examples.
0.358.0 — 2026-11-09
- Chat view preference (bubbles or room)
0.357.0 — 2026-11-09
- Cam camera settings (cam.settings@1)
0.356.0 — 2026-11-09
- Shoes product contract (shoes.product@1)
0.355.0 — 2026-11-09
- Daily quest contracts and step contribution
0.354.0 — 2026-11-09
- Vibe compare and Exchange chat export contracts (the Chat move)
0.353.0 — 2026-11-09
- Add
actor.ask@1: durable approvals, questions, personal steps and sign-in hand-offs, linked to the person’s Actor and goal, with evidence and an answer or decline.
0.352.0 — 2026-11-09
- The menu's home screen and wall (M1):
network.home-screen@1,network.menu-feeds@2(order and off; v1's on reads as
the start of the order),network.frame-today@1,community.status@1,community.pulse-contribute-request@1and the
person-granted capabilitycommunity.pulse.contribute, with fixtures and the manifests' routes.
0.351.0 — 2026-11-09
- Add the five public Report AI comparison response contracts and fixtures, and list their cached public routes in the Report service manifest.
0.350.0 — 2026-11-09
- Define credential-free blind fill request, encrypted grant, and outcome contracts, plus the
run.fill.approvecapability.
0.349.0 — 2026-11-08
- Add
identity.emails@1andidentity.email-add-request@1and theidentity.emails.readcapability for a person's verified, privacy-limited email addresses.
0.348.0 — 2026-11-08
- Service manifests:
studio(OpenVibe.Studio at openvibe.studio, live: Photo and Light in the browser), and
connectlives athttps://connect.openvibe.link(its home on OpenVibe Link since 11-08;connect.openvibe.website
stays as the second domain). The registry still gave the old origin, so the sign-in canary read a 302 for Connect.
0.347.0 — 2026-11-08
- Add
identity.trust@1andidentity.trust-request@1for account and guest abuse signals, plus the app-grantable
identity.trust.readcapability.
Responses contain coarse age bands and aggregate counts only; IPs, emails, last-seen timestamps, service user ids and
linked account identities are forbidden by the schema and fixtures. - Service manifests:
locker(OpenVibe.Locker at openvibe.locker, live; it owns thelockernamespace), and
computeris live (its exposure was still "repository").
0.346.0 — 2026-11-08
actor.skill-listing@2(2.1.0) gainsvisibility(plan HO11, the agent writes its own skills):public(the
default, and what every listing is today) orprivate, meaning only its publisher sees or installs it. Additive:
the field is optional, so a listing without it stays public and nothing that exists today changes shape. A private
listing'spublisher.kindmust beperson: OpenVibe's own skills are always public. JSON Schema states both the
enum and that rule, and the fixtures hold it.
0.345.0 — 2026-11-08
- Add
actor.approval-answer@1(plan HO12, the phone as the agent's eyes and hands): the person's answer to an
approval that asked for the phone's camera or its location. The person does the thing themselves, and the answer
carries the result back to the step as untrusted input.decisionisanswer, and exactly one of: photo:media_id, a private Media object the person took in the system camera (JPEG, PNG or WebP, at most
10 MB, EXIF stripped by Actor); the step reaches it through a short-lived signed URL;location:lat-90 to 90,lng-180 to 180,accuracy_m0 to 100000 metres andprecise. A coarse answer
(precisefalse) carrieslatandlngto at most two decimals; JSON Schema cannot count decimal places, so
Actor rounds the share and the repository's suite checks the rule.
The answer has nosecret,tokenorurlfield, and a decline stays the ordinary denial.actor.skill@1(1.1.0) andactor.skill@2(2.1.0) gaindevice.camera,device.locationanddevice.notifyin
requires.kinds, so a skill's steps may be one of those approvals like any other HO1 kind. Additive: nothing that
exists today changes shape.
0.344.0 — 2026-11-08
actor.trigger@1(1.2.0) gains the mention kind (plan HO13, standing intents): a trigger that waits for the person
to say one of their phrases in their own conversation with their own agent. Additive:kindmay now bemention;when.mentionholdsphrases(one to five, 2 to 80 characters each, trimmed) and
match(anyorall), whilewhen.wordsstays the card's line ("When you mention the release");firesmay only beonce_per_conversation: the trigger fires at most once in each conversation;expires_atis required for this kind and at most 90 days aftercreated_at(the default is 30). JSON Schema
cannot compare two dates, so Actor enforces the cap, and the repository's suite checks the fixtures and the rule.- A mention trigger listens only to the person's own words to their own agent: never anyone else's messages, never a
room or a stream chat, and never the agent's own answers. Matching is case-insensitive, on word boundaries, after
Unicode normalisation. Nothing that exists today changes shape.
0.343.0 — 2026-11-08
- Add
actor.skill@2andactor.skill-listing@2(ADR-060, plan HO8): a skill may now bring code that runs in a
sandbox instead of only a prompt.runsispromptorsandbox; a sandbox skill carries 1 to 5 JavaScript
tools(name, description,entrynaming one of its resources, a JSON Schema subset forargs,net
deny/openvibe-only/publicdefaultdeny, and limits under 30 s / 256 MiB), and the code itself is an
ordinary text resource (.js, at most 64 KiB) in the same integrity hash.requires.kindsgainsskill.run.
The v2 listing pins each code resource's Media id and sha256 and lets a scan finding name the tool it is about.
Code never runs on an OpenVibe server, never outside a sandbox and never with a secret: it runs as a Run
functionjob on a Link that declared the skill runner.actor.skill@1andactor.skill-listing@1are
unchanged and remain what a prompt-only skill publishes.
0.342.0 — 2026-11-07
- Add
mail.agent_inbox.received@1(track HO6, channels): a message arrived at an agent's own address and the person has switched that address's answering on, so their agent may read it. The payload names the inbox and the agent, the owner, the mail server's message id, the sender, the subject and a plain-text excerpt of at most 4000 characters. It never carries the attachments, the HTML or the whole body: the agent's system reads the text throughmail.agent.read, on the owner's behalf, once it has decided to answer. Mail publishes nothing for a sender on the person's block list or a message the mail server marked as spam, and nothing at all until the person turns the agent's switch on. - Add
mail.agent-inbox-message@1, the one message an agent reads: the sender, the addresses the mail server stamped at delivery, the subject, the text cut to 4000 characters, and the threading headers a reply needs. Never the HTML, never an attachment, and never a sender-written Delivered-To. The message is data from a stranger, and any instruction in it is that stranger's. - Add
mail.agent-reply-request@1andmail.agent-reply-result@1, an agent answering one such letter: the body is plain text, the recipient is the sender of the message being answered (the same address may be named, never another), and the reply carries In-Reply-To and References so the thread stays one thread. The result says whether the mail server took it —sent, not "delivered", since a later bounce is not knowable at that moment. - Add
mail.inbox-answering@1, the switch behind all of it: off by default, per agent, with when the person last set it. - Add the capabilities
mail.agent.read,mail.agent.replyandmail.agent.answering. The first two are loopback-only and first-party: only a token that names the person (on_behalf_of) and the agent's own inbox reads a letter or sends a reply, and only OpenVibe.Actor is granted them. The third is the person's own switch, under themail.addresses.writea caller already holds. Themailservice manifest lists all three and now producesmail.agent_inbox.received. - Additive only: five new contracts, three new capabilities and one manifest field; nothing that exists today changes shape.
0.341.0 — 2026-11-08
- The actor capabilities name the canvas routes (plan HO9):
GET /api/v1/me/canvasesandGET /api/v1/me/canvases/:idunderactor.task.read, andPOST /api/v1/me/canvases/:id/eventsunderactor.task.create. The documents areactor.canvas@1(0.340.0); a button's label starts a normal turn as the person, and a checklist tick flips the item and is told to the next turn. No schema changed.
0.340.0 — 2026-11-08
- Add
actor.canvas@1(ADR-059, plan HO9): an agent's live panel beside the conversation, as data. A canvas is a
list of blocks (a heading, text, a list, a checklist, a table, a metric, a bar or line chart, a picture from
openvibe.media, a link, a button) drawn by one renderer (OpenVibe.Sharedov-canvas.js) wherever it is shown. There
is no HTML, style, script or frame; text is plain. A button only sends its label to the agent as the person's own
message, and ticking a checklist item tells the agent which item changed: a canvas never acts by itself.version
only grows, and the agent replaces the whole document.
0.339.0 — 2026-11-08
- The batches contract says what cancelling does. Only the prompts that never had a run are cancelled, and
nothing is charged for them. A prompt that already has a run (the provider is working on it) goes on and
settles on its own path: it keeps its status, the answer says so, and nobody is told it was not charged. The
batch itself is cancelled only when nothing is left in flight. - The prompt's
reasonnow names the three notes a customer can read: it expired (it was not charged), it was
cancelled before it ran (it was not charged), or it was already sent to the provider (it finishes and is charged).
0.338.0 — 2026-11-08
actor.trigger@1gains the goal kind (plan HO3): a trigger that keeps working toward a goal on a schedule. Additive:kindmay now begoal, andstatemay bedone(a goal ended itself when its done-test passed);paused_reasonaddsdone,budgetanddeadlinebesidepersonandfailed;- the optional
goalobject says the goal in the person's words, thedone_testthe agent answers yes or no each run,
runs_usedagainstruns_max,spent_usdagainstbudget_usd,deadline_at, the last run'snot_yetreason and
itsverdict; - the optional
answer_in_chat(default true) says whether each run's answer is posted into the conversation that made
the trigger, under its card, andnotify(default false) whether the person is also told through OpenVibe's
notifications. - Nothing that exists today changes shape: a schedule or event trigger without the new fields stays valid.
actor.task-event@2gains thetrigger-runstep (2.2.0): a routine's run posted into the conversation that made the
trigger, under its card. Additive:trigger_idnames the routine,runsays which task ran and how it ended
(ok,failed,needs_you),textis its answer or the one line saying why it did not finish, andsourcesare
the addresses it read (at most 8). An event without them, and thetriggercard step, are unchanged.
0.337.0 — 2026-11-07
- Add
actor.skill@1andactor.skill-listing@1(ADR-058, plan HO2: the skills registry's skeleton). A skill is a
document an agent loads to do one kind of job well: a slug, a name, a one-line description (the only part an agent
reads before it loads it), a version, Markdown instructions, up to ten text resources, andrequires(the approval
kinds, connected apps and hosts it may ask for). It grants nothing: every step still goes through the agent's level
and approvals. A v1 skill runs as a prompt only (no code, no binary, no install recipe). Its integrity hash shows the
file was not edited; it is not a signature, and the author in a document is a claim. - The listing is the registry's record every site shows: the document, the publisher from the registry's own record,
the scan (pending,passed,flagged,failed, with findings) and the curator's state (active,stale,
archived, the last use and a near-duplicate). A passed skill installs in one tap, a flagged one after the person
reads the findings, a failed one never; a stale or archived one is not offered.
0.336.0 — 2026-11-07
- The run's options carry the latency class the caller asks for:
interactive(answer as soon as the provider can),
background(minutes; the run is priced on the cheapest tier that can wait) orbatch(hours; the run is queued and
answered through a provider's own batch API). A batch run may also saydeadline_hours(1 to 72): how long the answer may
take. The class is the workflow's own (the route'sconstraints.latency_class): a caller may ask for a slower class and
never for a faster one, and a faster ask is not refused — the run happens in the workflow's own class and says so. - The run's answer carries
latency_class(the class the run really ran in),service_tier(standard,flex,
batch,offpeak,local: the tier it was priced on — the one the provider served or the one the router chose) and
latency_clamped(the class asked for and the class used, when the ask was clamped). - Add the batches contract:
ai.batch@1,ai.batch-item@1,ai.batch-create-request@1,ai.batch-create-result@1and
ai.batch-read-result@1for/api/v1/batcheson OpenVibe.AI. A batch is a queue of many prompts that are answered
later, at half the retail price; the batch says where it stands, and a prompt that reaches its deadline without cheap
capacity expires and is never charged. - Add the grants
ai.batches.create(open a batch, cancel one) andai.batches.read(read the caller's own batches).
A first-party service opens a batch on the network's own account withai.batches.create; a person or a developer app
pays with its own account.
0.335.0 — 2026-11-07
- Add
actor.voice@1: an agent's voice as a file, and nothing else. The document carries the agent's name, a short bio, its instructions (the house voice it speaks in), its rules, its default approval level (ask,auto-edits,approve-for-me,full— the levels ofactor.agent@1), the model it prefers and the connected apps it may use (ids only, never a key), an optional face (an avatar ref), an optional author and acreated_at. It never carries memory, a connector's token or a file. - The document carries an integrity block, not a signature:
integrity: { alg: "sha256", hash }, where the hash is the sha256 over the canonical JSON of the document. It shows the file was not edited after it was written. It says nothing about who wrote it: anyone can write a file that names an author and compute its hash, so the author in a document is a claim and the contract says so. Only the service that owns an agent may vouch for its author, in its own record. - The contract says exactly which fields the canonical JSON holds and in which order, and
created_atis not one of them. The author may be absent: a document may name nobody. - Importing a voice makes a new agent at level
ask, whatever the file says: a borrowed agent starts cautious and the person raises it themselves. Valid and invalid fixtures cover a full voice, a minimal one, a document carrying memory, one carrying a connector's token and one with a level that is not a level. - Additive only: a new contract and its fixtures; nothing that exists today changes shape.
0.334.0 — 2026-11-07
- The
chatmanifest namesopenvibe.party, the Watch Together host OpenVibe.Chat serves besideopenvibe.chat
(Party watch v1, plan R1). Chat's service manifest is what services check a party link against: a media party plays a
Media ref or an https URL on a host a manifest names, so a party started from an OpenVibe page passes and a link to
somebody else's server does not. Thewww.name only redirects, so it is not listed.
0.333.0 — 2026-11-07
- The
networkmanifest names the two hosts Network serves since 2026-11-07:openvibe.my(the account hub's own home,
Network#646) andopenvibe.link(OpenVibe Link's home, Network#644). A service that builds its CORS list or its
checks from manifest domains (Network's first-party origins, Chat's Bearer-only DM grant, the registry's nightly
browser check, Space's reserved names) now includes them. Thewww.names only redirect, so they are not listed.
0.332.0 — 2026-11-07
- Add
common.control-lease@1, the shared control lease (seven domains plan B3): the thing a lease controls, its holder (aperson, anaiornobody, with the holder's subject or null), when the holder got the controls, an optional absoluteexpires_ms, the subjects watching and aseqthat increments on every holder change, expiry or take-back. A watcher-only change does not incrementseq. The authority that owns the thing enforces the rules; Chat hosts a room's lease, names the thingchat.room:<slug>and accepts a control change only from the current holder, while take-back by the room's owner always wins; only the owner hands the remote to anai, and a person holder who leaves keeps it for a minute. - Add
common.sync-clock@1, the shared timeline (B4): the room, the media (a Media ref or an https URL; Chat accepts only a host an OpenVibe service manifest names, so Party plays OpenVibe media), the position atat_ms, the rate, whether it is paused, who set it and aseq. A player computesposition_ms + (authority now - at_ms) * ratewhile it plays andposition_mswhile it is paused. Chat stampsat_msandseqand stores the latest state inroom_sync_clocks(the memory copy is the room's live state). - Valid and invalid fixtures cover a person, AI and free lease, a lease with a time limit, seq zero, a nobody with a subject, a duplicate watcher, a URL and a Media-ref clock, a clock at a rate and paused, an http URL, a bad room and a bad media object.
0.331.0 — 2026-11-09
- Add
actor.trigger@1: a trigger made in an Actor conversation — itstrg_…id, owner, agent, task, kind (scheduleorevent), the plain-language and machine schedule (a five-field cron in the person's timezone) or Watch event pattern and filter, the next run, the last run's result (ok,failed,needs_you), state, why it is paused, the consecutive failure count, the Watch subscription's own state and the ten-minute undo window. Owner-only: another person's trigger is the same 404 as one that does not exist. actor.task-event@2gains an optionaltriggerand thetriggerstep: the card as it is created, edited, paused, resumed, undone or deleted in the conversation travels with the event, so a reader renders the live card without a second fetch. Additive: an event without one stays valid, and the task record is still the source of truth.- Additive only: a new contract and an optional field plus one new step value; nothing that exists today changes shape.
0.330.0 — 2026-11-07
- Add the
mailservice manifest:openvibe.emailas the site Email (iconmail, the shared glyph font's E054), tagline "An address for every sign-up", the receive-only wording, legal profileservice, and position 7, directly after Chat. It declares exposurelive/service, port 5250, databaseov_mail, the Stalwart mail server,/api/healthand/api/ready, its shutdown and due-based recovery, an expand-only rollback, and the purge lease. - Add the two capabilities OpenVibe.Mail's API already checks:
mail.addresses.write(make and retire a mask; make an agent inbox) andmail.messages.read(the person's addresses, message metadata and the newest burner code, never a body). Both are first-party,owner-constrained, and name their routes. Their request and result schemas are recorded incompatibility/capability-schema-gaps.jsonfor now, like the config.manage capabilities added in 0.315.0. - The manifest lists no
eventsProducedyet: the service publishesmail.mask.createdandmail.received, but their payload contracts are not in this release. - Sites from the old position 7 up move one place (Services becomes 8, … Connect becomes 52) so Email sits beside Chat without breaking the unique-position rule. No contract changes shape; the only data change is the site order.
0.329.0 — 2026-11-07
- Add
mail.mask@1: a per-site address on OpenVibe.Mail that delivers into its owner's OpenVibe mailbox and nowhere else. It carries themsk_…id, the owner's Network subject, the<words>.<four characters>@<mask domain>address, the person's label and purpose, whether it is enabled (a disabled mask leaves the SQL directory Stalwart reads, so it bounces) and when it was made. M1 is receive-only, so this is metadata: no body, no forwarding target. - Add
mail.burner@1: a throwaway receive-only address with itsbnr_…id, an owner (null for the ten-minute burner made without an account), the eight-character address on a rotating burner domain, the expiry,first_message_onlyand the creation time. The one-time read token a create call returns is deliberately not part of the resource. - Add
mail.agent-inbox@1: an agent's address<agent>.<user>@openvibe.email, itsagi_…id, the owner, the cleaned agent id and the creation time. The mail lands in the person's mailbox; one agent has one inbox. - Add
mail.message-summary@1: the one shape a list API returns for a message — id, sender addresses, subject and received time.additionalPropertiesis false, so abody,previeworhtmlfield fails the contract rather than leaking into an API; the body is read only by the verification-code endpoint, in memory. - All four are new contracts, not changes to existing ones, and the minor is expand-only. Valid and invalid fixtures cover a disabled mask, a guessed address, an anonymous and a one-message burner, a bad owner or agent id, a non-address, and a summary that carries a body.
0.328.0 — 2026-11-07
- Add
actor.assignment@1: one node of the tree of delegated work (plan §12) — id, root, parent, depth, origin (person,routine,outside), mode (work,consult,notify), reply (resume,poll,none), the agent and task it runs as, the node's level and effective level, the root's budget (limit, spent and remaining), state and timestamps. A node is one hand-off: a person giving Actor a task, a routine or Watch trigger starting a run, an agent handing work to another agent, or Actor starting a Codes or Space task. The effective level is the higher of the agent's own and the one inherited along a person's or routine's line; outside work never passes a level down. A cancel cascades down the tree, and a root's budget stops its children when spent.GET /api/v1/assignments/:idanswers the node and its children andPOST /api/v1/assignments/:id/cancelcancels the subtree; both are owner-only and another person gets 404. An existing task gets a root lazily. - Add the capabilities
actor.assignment.readandactor.assignment.cancel, and name them in Actor's service manifest. They are the two assignment routes above. actor.task-event@2gains an optionalassignment_idon a step event, so the Dock's timeline can draw the work tree later. Additive: an event without one stays valid, and the task record is still the source of truth.
0.327.0 — 2026-11-07
- One Computer across Surf, Actor and the Dock (plan 2026-11-07: "Surf, Computer and Actor are one experience"):
platform.task@1gains optionalcomputer(session_id,machine,where,cost_hint,driving) — the browser or desktop session a running task opened, wherever it runs.session_idis OpenVibe.Run'sses_…; it is null only when the desk runs directly on the person's own machine through OpenVibe.Bot, where there is no Run session.whereisyours,homeornetwork, andmachineis the person's own word for it. actor.task-event@2andagent.timeline-entry@1carry the samecomputerobject by$ref: the task's step in the Dock and the task record read the same fields, never a copy.run.session@1gains optionaltask_id(the Actor task that asked for the session, so the session points back at the task) andcurtain(the privacy screen: while it is up the session's still answers the curtain picture, never the screen).run.session-create-request@1gains optionaltask_id.- The
run.session.startedandrun.session.endedevent payloads carry the same optionaltask_idandcurtain, so a session's own events stay valid with the new session shape. - Capabilities name the routes:
run.session.readgainsGET /api/v1/sessions/{id}/still,run.session.controlgainsPOST /api/v1/sessions/{id}/curtain,actor.task.readgainsGET /api/v1/tasks/{id}/still, andactor.task.creategainsPOST /api/v1/tasks/{id}/takeoverand…/giveback. - Additive only: every new field is optional and nothing that exists today changes shape.
0.326.0 — 2026-11-07
- Add
network.menu-feeds@1: the cards a person chose to show in the OpenVibe menu's "Choose your feeds", in their order, following them across every site.onholds up to four<site>:<cardId>ids (lower-case letters, digits and dashes) andupdated_atsays when the choice last changed. OpenVibe.Network keeps it atGETandPUT /api/v1/me/menu-feeds; a person who has never chosen gets{ on: null }from the GET. An empty array is a cleared choice. - Additive: a new contract only; nothing that exists today changes shape.
0.325.0 — 2026-11-07
- Add
media.vod@1andmedia.clip@1: one recorded stream and one clip as OpenVibe.Media's API answers them. Both carrywatch_id, the id openvibe.video addresses a watch page by (openvibe.video/watch?v=<watch_id>), and the shape around it that consumers already read — the numeric id (internal), the owning tenant, the app-local user ids, title and status, duration and size, the file basename,playback_url, thumbnail, storage provider, visibility, view counts and times; a clip also names the recording it was cut from, its window in that recording and whether an automation cut it.watch_idis additive and optional (11 characters of URL-safe base64 from 8 random bytes, one id space across VODs and clips, fixed for the row's life and never the numeric id), because a row written before Media's backfill may answer without one. - Valid and invalid fixtures cover a public recording with a watch id and an unlisted one before the backfill, a person-made clip and an AI clip, a watch id of the wrong length, one with a character base64url never has, one with a slash, and an unknown visibility.
0.324.0 — 2026-11-07
- Space's builder API moves under
/api/v1/builder/spaces:GET /api/v1/spaceswas the forum's old API (it lives on OpenVibe.Community since 2026-11-07, and Space still answers it with a redirect), so the API the person's own agent works through needs an address of its own. The capabilities name the new routes:space.build.read(GET /api/v1/builder/spaces,…/:id,…/:id/files,…/:id/files/:path,…/:id/preview),space.build.create(POST /api/v1/builder/spaces),space.build.write(PUT /api/v1/builder/spaces/:id/files) andspace.build.publish(POST /api/v1/builder/spaces/:id/publish, and the person's answer atPOST /api/v1/agent/approvals/:id/decide). - No contract shape changes: the bodies and the capability ids stay as they were.
0.323.0 — 2026-11-07
- Space's builder API says two more routes in its capabilities:
space.build.readnow namesGET /api/v1/spaces/:id/files/:path(one file of one of the person's own spaces), andspace.build.publishnamesPOST /api/v1/agent/approvals/:id/decide(the person's answer to the agent's request to publish, which OpenVibe.Actor passes on with the person's own token). - No contract shape changes:
space.build.readandspace.build.publishkeep the bodies they had.
0.322.0 — 2026-11-07
- Add
actor.agent@1: one of a person's agents as a contact (plan §12 A-1) — id, owner, name, face, voice, model (engineruntime / own-keys / open-gpu / link, plus the model id), computer (null or a Computer kind and placement), connected app ids, OpenVibe Memory scope id (or null), approval level (ask,auto-edits,approve-for-me,full) and when it was added. Levels default to ask; money, passwords, deletions and sending to a new recipient always ask at every level, as a server-side floor. - Add
actor.agent-list@1: a signed-in person's own agents (GET /api/v1/agents), Vibe first. Vibe is created on the first read and is not deletable. The public agent-system catalog keepsactor.agent-list-result@2and now has an explicitGET /api/v1/agent-systemsfor a signed-in caller. - Add
actor.level-change@1: the body ofPUT /api/v1/agents/{id}/level; optionalagent_id,thread_idandreasonare echoes, the path names the agent. actor.task-create-request@1gains optionalagent_id(the contact the task runs as; absent means Vibe) andlevel(the thread's own level).platform.task@1gains optionalagent_id,level,effective_levelandagent_level. The effective level is the higher of the agent's level and the person's own thread line; it never inherits from another person's or a service's work.- Name the contact routes in
actor.agent.manageand the catalog and presets routes inactor.agent.read; add valid and invalid fixtures for the three new contracts.
0.321.0 — 2026-11-07
- Space's builder becomes a task of the person's one agent (plan 2026-10-22 §Z, stage Z1). Add the contracts of Space's builder API:
space.build-space@1(one of a person's own spaces: its id, slug, name, description, whether it is published and where, and when it changed),space.build-list@1({ spaces }or{ space }),space.build-files@1(the space's files, each a path and its whole content),space.build-create@1(the body of a request for a new space),space.build-preview@1(where the space can be seen now, its file paths, and whether it is live) andspace.build-publish@1(pending,publishedordeclined, with the request the person answers in the Dock). - Add the capabilities
space.build.read(list and read the person's own spaces and their files),space.build.create(make a new space),space.build.write(write the files of one of them) andspace.build.publish(ask to publish; the person answers before anything goes live). A first-party service names the person inX-OV-Subject, and only that person's own spaces are in reach. - Additive: nothing that exists today changes shape.
0.320.0 — 2026-11-07
frame.menu-card@1items gain an optionalimage:src(https on the publishing site's own origin or anopenvibe.*host, at most 400 characters), optionalwandh(whole pixels, 16–1920) and an optionalaltof at most 120 characters. Network keeps an image whosesrcpasses the same host rule as the item'surl, drops one from anywhere else, and passes it through inGET /api/frameso the Frame menu and Network's/mycan draw a thumbnail.- Additive: every item without an image stays valid, so an older publisher file keeps passing and an older reader ignores the field.
- Valid fixtures cover an item with a full image and one with only
src; invalid fixtures coverhttp, a width under 16, analtover 120, a missingsrcand an unknown image field.
0.319.0 — 2026-11-07
- The merged public site: OpenVibe.AI is no longer a site of its own. Its service manifest keeps the API, the run receipt and the operator console but drops the
siteblock, so Network's Frame lists Exchange instead of AI.manifests/products/ai.openvibe.services.jsoniskind: moved, points at Exchange and keeps the API address, and Exchange's own site block now carries the merged tagline ("Every AI model, one account") and what it does. - No contract shapes change.
0.318.0 — 2026-11-07
- Add
network.presence@1: one person's online status as another may see it —online,away,dnd,invisibleoroffline, an optional status line (80 characters) and one emoji, whether they are streaming on OpenVibe.Live (live), and when it changed. OpenVibe.Network owns it; the state is derived from a heartbeat (online under 2 minutes, offline after 3) and the last input (away after 10 minutes), and invisible orshow_statusoff is seen as offline. - Add
network.presence-update-request@1: the optional fields ofPUT /api/v1/me/presence— the chosen state (auto,dnd,invisible), the status line and emoji, and the "Show my status" switch. - Add the event
network.presence.changed, at most once per person per 30 seconds and only for a real change. Its payload is the public view: an invisible person is sent as offline with no status text or emoji, and the state list has noinvisible. - Add the capabilities
network.presence.read(OpenVibe.Network'sGET /internal/presence, for Chat) andchat.dm.peers.read(OpenVibe.Chat'sPOST /internal/chat/dm/peers, for Network's "follows or has a DM" rule), and name them in the two service manifests. - Valid and invalid fixtures cover the presence, the update request and the event, so a bad subject, an unknown state, an over-long status or a second emoji fails the run.
0.317.0 — 2026-11-07
- Add
frame.menu-card@1: one card a site publishes for the network's Frame menu (the menu's network cards). A card has a stable id and site, a title of at most 60 characters, a kind (rail,rowsorchips), up to six items with a title of at most 80, an optional meta line of at most 120 and an https URL, an optionalmorelink with a label of at most 24, the time it was built and its ttl. A URL must be https on the publishing site's own origin or anopenvibe.*host; the text is plain words and Network strips markup and drops unknown fields. - Add
frame.menu-cards@1: the public file each open site serves at/.well-known/openvibe-menu.json— an array of at most three cards from that site. An empty array is valid (the site has no card right now); Live serves its rail with empty items when nobody is live, and Network then skips it. - Valid and invalid fixtures cover a live rail with and without items, a Games rows card, a three-card file, an empty file, a title over 60, seven items, an unknown kind, an
httpURL, an unknown field, a ttl under 30, four cards and a card with a bad timestamp.
0.316.0 — 2026-11-07
- Add
agent.timeline-entry@1: one entry of the agent's timeline (design 2026-11-07 §2) — one step of the agent's work, in one mode, for one person. It carries the mode, the product, the step's own id, a plain title, when it started and ended, its status (running, waiting, needs_you, done, failed, stopped), the placement (where it ran and why), the cost, a link to the step's page, the one-line reason when it failed, the transition sentence when the mode changed, and the audience (private is Only me, the default). It never carries a prompt, a diff or a page. - Add
common.agent-step@1and the three eventsagent.step.started,agent.step.updatedandagent.step.ended: the one shape every mode publishes when the agent does something (Chat, Codes, Run, Watch, Live, Surf), with the person's subject on the envelope. The payload is the step's shape only — a title, an outcome, a link, a cost — and never the step's content: a prompt, a diff, a page, a message or a file is refused by the schema. Theagent.*namespace belongs to the network (likeprovider.*), so any first-party mode may publish into it; OpenVibe.Actor registers the family in Contracts and keeps the one timeline behind the Dock. - Add
agent.timeline-list-result@1: what the Dock's Agent panel reads — the step happening now, what needs the person (oldest first), the entries themselves (newest first), the next cursor, and the per-mode counts so a filter never hides without a count. - Add
actor.timeline.read:GET /api/v1/agent/timeline, the person's own timeline with the cursor and the mode and needs-you filters. Only their own entries; another person's entry is a 404. - Valid and invalid fixtures cover a step that starts, waits and ends, a timeline entry and a list, a payload with a prompt or a diff in it, an unknown status, a mode that is not one of the seven, and an entry of another person.
0.315.0 — 2026-11-07
- The owner's Setup tab reaches seven more services:
<service>.config.manageforchat,connect,deals,work,sources,designanddomainsis now active and listed in each service's manifest, because each mounts openvibe-shared/config's routes on/internal/config(GET /internal/config,GET|POST /internal/config/:namespace,PUT|DELETE /internal/config/:namespace/secrets/:key,POST /internal/config/:namespace/test/:key). Only Network's admin proxy, acting for the owner, holds them and they are never grantable to apps.media.config.managestays planned until Media mounts the routes. - Add
blog.review.ai_editor,news.review.ai_editorandwiki.review.ai_editor: the editorial queue's AI editor decision (approved or rejected; approved or needs changes on Wiki) recorded by the first-party service principal acting as itself (asvc:principal with noX-OV-Subject) through Blog'sPOST /api/v1/posts/:id/reviews, News'sPOST /api/v1/stories/:id/reviewsandPOST /api/v1/briefs/:id/reviews, and Wiki'sPOST /api/v1/pages/:id/revisions/:n/review. An approval lets AI-written text publish and index and the page says "Checked by OpenVibe's AI editor" with its date, never "Reviewed by a person"; each is granted only to the orchestrator's service principal. Their requests and results are a recorded schema gap (compatibility/capability-schema-gaps.json). generated/refreshed: Connect and Design gain an OpenAPI document now that each has an active capability, and Blog, Chat, Deals, Domains, News, Sources, Wiki and Work gain the new operations.
0.314.0 — 2026-11-07
- Add the capability
live.agent_sandbox.register(Agent Streams S6): the chat plays sandbox worker's check-in on OpenVibe.Live,POST /api/streams/agent/:id/plays/worker, owned by Live and internal. Only a first-party service token whose principal holds it may register a worker, and the token names the person it works for inX-OV-Subject, who must own the stream. The owner's own session, a desk ticket (wpt_) and a person token are refused: an owner who could register a worker would declare their own unisolated machine a sandbox. The worker reports the isolation facts Live requires (no host network, no credentials, no profile, egress through the proxy, an ephemeral workspace) and Live derives health only from a check-in within the last minute; Live stores no endpoint and never calls the worker. Name the capability in Live's service manifest. - Add
live.agent-sandbox-worker-request@1: the worker's check-in body, which names the five isolation facts Live reads exactly (host_networkfalse,credentialsfalse,profilefalse,egress_proxytrue,workspaceephemeral) and may carry the worker's own checks, limits, versions and counts. A worker that cannot say each of the five is not registered. Addlive.agent-sandbox-worker-result@1: the worker's state for the stream's owner, with the reason when there is no healthy one, the last check-in and the minute a check-in counts for. Live never returns an endpoint: there is none. - Valid and invalid fixtures cover a full worker check-in and an isolation-only one, a worker with the host's network and one that cannot say there is no profile, and a healthy worker, a stale one, a missing stale window and an unknown state code.
0.312.0 — 2026-11-07
- Add the Codes skills-hub records (the Compute plan §5, E6).
codes.skill@1is one skill, rule, MCP server, command or hook: its owner, kind, stable slug, title, summary, the four sharing audiences (private,people,link,public), the harnesses it is written for, the newest version and that version's body. Aprivate,peopleorlinkrecord is never in the gallery; onlypublicis. The body is untrusted Markdown and the page renders it through the markup gate. - Add
codes.skill-version@1: one immutable version of a record, keyed byskill_idand a growingversion, with the body, summary, tools, audience, author and the note that says why it was written. A rollback copies the chosen version into a new one rather than rewriting history, so a Link that synced version 3 can still name it. - Valid and invalid fixtures cover a public skill, a private rule, a people-shared MCP record, versions 1 and 4, and the bad ids, kinds, audiences, tools, bodies and authors.
0.311.0 — 2026-11-07
- Add
<service>.config.managefor the eight services that hold an owner input and that Network's admin proxy now reaches for the owner's Setup tab (OWNER-SETUP-AND-ADMIN-CLARITY-DESIGN, 2026-11-07):chat,connect,deals,work,sources,design,domainsandmedia. Each is internal, held only by Network's admin proxy acting for the owner, never grantable to apps, and planned until its service mounts openvibe-shared/config's routes on/internal/config; the service then turns it active and lists it in its manifest (Deals' own test pins that list, so listing it early would break its pin bump). Planned capabilities verify like active ones, so Network's grant works the day a service mounts the routes. - Every
<service>.config.manage(the nine active and the eight planned) namesPOST /internal/config/:namespace/test/:keyamong its routes: openvibe-shared 4.125.0's test hook, which tries a stored value with the provider on the server and answers{ ok, message }in one line that never carries a secret. common.config-namespace@1(description only): the summary's schema may carry the annotations the Setup tab and the clear admin panel read,x-owner-input,x-required-for,x-enum-labels,x-advancedandx-example, beside the D11 ones (andx-unitnamesseconds). No shape changes.
0.310.0 — 2026-11-07
- Apps ask for consent per purpose at sign-in (the consent plan's C4). An app adds one scope
consent:<purpose>per purpose to /oauth/authorize, beside its other scopes. It may ask for every purpose of the consent family except the retiredai.looks:ai.train,data.public,face.recognizeandapp.data. Any otherconsent:scope is refused withinvalid_scope. The consent screen lists each purpose in plain words, nothing ticked, and the person can sign in with every purpose refused. A refused purpose is not asked again by that app for 30 days, unless the person asks for it again on their account page. - Add
network.consent-claim@1: theconsentclaim of the tokens Network issues from that sign-in (a first-party user token, a Dock token or an app token). It holds exactly the purposes the sign-in asked for that the person granted to that app and that are active when the token is issued,[]when none. It never holds a refused purpose or another app's grant, and the app learns only "not granted". The claim is absent when no consent scope was asked. Every new token works it out again, so a purpose turned off is gone from the next one. identity.service-token-claims@1gains the optionalconsentclaim (additive): an app token from the authorization-code flow carries it when the sign-in asked for consent scopes.- Add
network.me-consent-apps-result@1: "Apps you allowed" on the account page (GET /api/v1/me/consent/apps), listing each app's granted purposes and the ones refused in the last 30 days (quiet, with the day it ends), with the words the app consent screen shows.network.consent.managenames that route andDELETE /api/v1/me/consent/:purpose/:client/refusal, which ends a refusal's quiet days so the app's next sign-in asks again. network.consent@1: an app's grant is one record per purpose, with the app asclientandsourceoauth.clientis no longer only forapp.data, andoptions.purposesis not written any more (kept so older records validate).network.consent-check-request@1'sclientmay name the app for any purpose: one app's grant never answers for OpenVibe itself or for another app. Descriptions only: no shape changes.- Valid and invalid fixtures cover a user token with one purpose, an app token with none and with all four, a retired, unknown, duplicated or missing claim, a claim that is not a list, an app's grant record, the account page with two apps and with none, a bad client id, a retired purpose, an extra key and a quiet refusal with no end.
0.309.0 — 2026-11-07
- Add
bot.machine-pool@1(the pooled machines design, 2026-11-06): several of one owner's machines on the same local network that serve one model together through llama.cpp RPC (rpc-serveron the members,llama-server --rpcon the head). OpenVibe.Network holds the record: the owner proposes it on /machines with two to eight of their own machines (the default head has the most free VRAM), and each machine reads it with its own node token and approves it on itself. A member'scertificateis null until it approves; then it is that machine's self-signed Ed25519 public certificate, which the other members pin for the pool's private link. The private key stays on the machine: a certificate slot holding anything withPRIVATE KEYin it is refused, and so is any field the schema does not name. A member'saddressis a private RFC 1918 address and prefix (never 0.0.0.0, loopback or a public address) and itspublic_ipis the address Network saw it from. The rules a schema cannot say are written in the description and checked by Network and Node: the head is a member, every member is the owner's today, all share one public address and one private subnet, the head's direct link probe to each passes, every key is its own, and any change of membership, owner, head or key revokes the pool so every machine approves a new one. - Add
ai.offer@1: one community AI offer as Bot reports it to Network and AI reads it back (the fields Network already stores: machine, owner, models, hours, concurrency, credit price, audience, readiness and health), with the new optionalpool. - Add
ai.offer-pool@1, thepoolpart of the AI offer:{ machines, head }, two to eight machine ids and the head, which is the offer's own machine. Network adds it from its approved pool record, never from what a machine reports, and leaves a member's own offer out while it is in a pool. It names machines only: no address, key or certificate reaches AI. One price, audience, hours, idle-only and verification apply to the whole pool; AI verifies a pool's answers as it would one machine's, keys that verification on the exact membership, keeps a new or failed pool to the free tier only, and labels it "Community pool (N machines)". network.node.self.managenames the five pool routes a machine calls with its own token (announce, read, approve, renew readiness, leave) inimplementedBy.- Valid and invalid fixtures cover a pool waiting for approvals, an approved pool of three, a single-machine offer, a pool's offer and one still waiting, a group offer, a missing head or owner, a one-machine pool, a repeated member, a private key in the certificate slot, a public, loopback or wildcard address, a port under 1024, and an address, certificate or key smuggled into a field the schema does not name.
0.308.0 — 2026-11-07
- Add
ai.memory-export@1(Memory M5): the one portable memory file. It carriesformat: openvibe.memory-export@1,version: 1,exported_atand every item's text, kind, scope, source, confidence and source reference. It deliberately has no ids, owners, merge links or conflict pair, so a file can be imported into another account without carrying anyone's identity, and a profile is derived from the items and rebuilt, never imported. OpenVibe.AI'sGET /api/v1/memory/exportwrites it andPOST /api/v1/memory/importaccepts the same document; both redact again. - Valid and invalid fixtures cover an export with items and an empty one, a wrong format/version and a scope that is an absolute path instead of
userorproject:<slug>.
0.305.0 — 2026-11-07
- Give the id kinds the S7 work needs a prefix:
newId('agent_stream_schedule')isscd_…(a scheduled public agent stream) andnewId('party')ispty_…(a watch party's id when a party is not named by its room slug). - Add
live.agent-stream-schedule@1(Agent Streams S7): an owner's schedule for a public agent stream — a time, a task template and the mode. Live starts it when the owner's desk is online; when the desk is not, the record saysmissedwithdesk_offline("didn't start: the desk was offline") and nothing runs. Achatplaysschedule keeps its time but waits for the owner's Go (waits_for_go), the S6 rule. The record carries the stream it started, its reminder count (the people who opted in, never who they are) and the page where it shows 24 hours before its time. - Add
chat.party@1(Agent Streams S7): a watch party on a public agent stream or its VOD, a Chat room of kindparty. On a VOD the position follows the host's; on a live stream it follows the live edge. A party is private by default, joining is by its link, and a listed party reaches the stream's page only as a count ("3 parties watching") — the count never carries names. - Extend
live.agent_stream.publishwith the schedule routes and the desk heartbeat:POST|GET /api/streams/agent/schedules,DELETE /api/streams/agent/schedules/:id,POST /api/streams/agent/schedules/:id/remind,POST /api/streams/agent/schedules/:id/goandPOST /api/streams/agent/desk/heartbeat. - Valid and invalid fixtures cover a scheduled stream, a missed one with the desk offline, a chatplays schedule that waits for Go, a missing task and an unknown state; a private VOD party, a live party with a link, a party made public and a party with a room id that cannot exist.
0.304.0 — 2026-11-06
- Give the id kinds the Agent Streams work needs a prefix:
newId('agent_stream')isags_…(an agent stream's id),newId('play_request')isreq_…(a chat plays request) andnewId('sandbox_session')issbs_…(the sandbox desk). Without them a service that had to name one of these ids had to build the ULID itself, andnewId('ags')threw.
- Add
chat.play-request@1(Agent Streams S6): one viewer's request for the chat plays desk to build or do something. A request is written with!do <request>(at most 200 characters) in an agent stream's room,agent:<ags_id>; one open request per person at a time, and an account younger than a day cannot ask. The request carries its votes, its state (queued,running,done,failed,skipped,removedorrefused), whether it is pinned, and the one-line reason it was refused (with the rule that refused it) when it was. A refused request carries no result; a finished one carries the outcome, the line the overlay and the voice said, and the scratch site the run left. - Add
codes.sandbox-session@1: the sandbox desk a chat plays session runs on. The desk is started with--shared— no profile, no keys, no person's files, public egress only and a fresh workspace, wiped at the end — and the session carries the owner's time box (5 to 30 minutes), the step budget, the cap (money and minutes), what it has spent, whether the owner armed it with Go, and the throwaway scratch site with the 24 hours it lives.egress_public_onlyis always true: no private address is reachable. live.agent-stream-control@1gains the controlwipe(additive): Wipe now stops the run and resets the sandbox. The other four controls (pause, curtain, mute, end) keep their shape.live.agent-stream@1gains the modechatplays(additive; the enum already carried it): a chat plays stream is public or unlisted, and it works the room's queue.- Add the capabilities
chat.play_queue.readandchat.play_queue.writefor Codes, the task's service, acting for the stream's owner (a node tokenon_behalf_of), and name both in Chat's service manifest. Chat chooses what the queue holds: a request enters it only after the house text filters and the safety check, one open request per person at a time, and the people and the votes in it belong to the room. - Valid and invalid fixtures cover the queued, finished and refused requests, a request that is too long, a refusal without a reason, an unknown state, the armed and running sandbox sessions, a session with no cap, a time box outside 5 to 30 minutes, a sandbox that is not public-only, and the wipe control, so a missing field or a bad value fails the run.
0.303.0 — 2026-11-06
- Add
chat.agent-digest@1(Agent Streams S5): what a Co-pilot room said to an agent between two of its steps. The agent never reads the raw room: it asks Chat for a digest and gets at most ten items and 1,500 characters. Each item names who (the display name and the handle), what (cut to 200 characters), its kind (question,suggestionorreaction) and its upvotes; a repeated line is one item with the number behind it. Chat chooses what goes in (repeats grouped, greetings and spam dropped, the most-upvoted questions and suggestions first) and who is left out (a person who is timed out or banned, whose account is younger than a day, or who set 'Agents don't read my messages'). A link is kept as its domain only; the code and the commands stay as text. - Add
chat.agent-poll@1: the poll an agent asks a Co-pilot room to run, and the result it gets back — the question and the two to four options the agent wrote, the window it is open for, the state (open,closedorvetoed) and the counts. An open poll carries no result, a closed one carries its counts and its winner, a vetoed one names who refused it. - Add
live.agent-stream-control@1: one of the four controls the owner and the channel's moderators have over a live agent stream —pause,curtain,muteorend— with who pressed it (the handle and the role: owner or moderator) and when, and whose pause is in force. - Add the capabilities
chat.agent_digest.readandchat.agent_poll.write(first-party), and name both in Chat's service manifest. The caller is Codes or Actor, the task's service, acting for the stream's owner (a node tokenon_behalf_of), so a digest is the owner's room and nobody else's. chat.preferencesis v2: it gainsagents_read_messages('Agents don't read my messages'). A v1 record upgrades with it true — joining a Co-pilot room and writing in it is the choice, and the person can take it back.live.agent_stream.publishnow names the controls (POST /api/streams/agent/:id/control,GET /api/streams/agent/:id/controls) and the step credit: a step may name the suggestion it took.- Additive: nothing that exists changes. Fixtures cover a digest over the ten-item cap, an unknown kind, a room that is not an agent room, a poll with one option and with five, an open poll carrying a result, an unknown control, a control with nobody behind it and a role that is neither owner nor moderator.
0.302.0 — 2026-11-06
- Add the capabilities
media.avatar.adoptandmedia.avatar.release(internal), and name both in Media's service manifest. After the 2026-11-06 incident (eleven avatars were soft-deleted with the public screenshot copies), Media records which avatar object each profile slot points at, and its delete refuses an object a working profile still shows. A product (Network forusers.avatar_url, Live for its own copy and the channel banner) records a slot withPOST /internal/avatar-adoptand drops it withPOST /internal/avatar-release. - Add
media.avatar-adopt-request@1/media.avatar-adopt-result@1(the slot:object_idmed_…,product,ref, the optionalsubject; the answer is the active reference) andmedia.avatar-release-request@1/media.avatar-release-result@1(a slot, an object or a person; the answer counts the released references, 0 when there were none). - Additive: nothing that exists changes. Fixtures cover a missing ref, an object id that is not
med_…, a release that names nothing, a product without its ref and a negative count.
0.301.0 — 2026-11-06
- Add
live.agent-stream-state@2(Agent Streams S4): the state the desk polls gains the voice (modewatch or narrated, thevoice, thepersonalitycalm, hype, dry or roast,muted,pausedwith its reason), the newestlinesto speak, andcaptions_url(the stream's WebVTT).@1is unchanged. - Add
chat.tts-speak-request@1andchat.tts-speak-result@1: the body and answer ofPOST /api/agent-voice/speakon OpenVibe.Chat (one line of at most 220 characters, an optional voice or the person's own; the audio, its MIME type and rate). - Add the capability
chat.tts.speak: a machine (a node token acting for its owner,on_behalf_of) asks Chat to speak a line in that person's chosen voice, never another person's. Chat's manifest names it. - Additive: nothing that exists changes. Fixtures cover a missing text, a line over 220 characters, a missing audio and a wrong MIME type.
0.300.0 — 2026-11-06
- Add
report.session@1: the report of one agent session, whatever ran it — a Codes task, an Actor task, a desk session or a session on a person's own machine (the Agent Streams plan, S3). It carries the id (rps_<ULID>), the owner (usr_…), the source (codes,actor,deskornode), the task (title ≤ 200 characters, the task's ref and its link back), the start and end, the worked seconds, the outcome (done,stoppedorfailed, withstopped_becausein plain words when it did not finish), the summary (≤ 600 characters), the timeline (the steps, the same shape aslive.agent-stream-step@1), the outputs (pr,file,page,deploy,cliporvod), the proof (the tests, the screenshots' media ids and the review's verdict), the cost and the models, up to five highlights, the agent stream it streamed on and the visibility (private,unlistedorpublic). The raw transcript, secrets and code are never in a report: the source service keeps the transcript for the owner, the house redactor runs over every text field before anything is stored, and a pull request is a link (its content shows only when the repository is public). - Add
report.session-write-request@1andreport.session-write-result@1: the body ofPOST /internal/session-reportson OpenVibe.Report and what it