---
title: "blog.changelog-entry@2 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/blog.changelog-entry"
updated: null
---

# blog.changelog-entry@2 · OpenVibe.Services

HTML: [blog.changelog-entry@2 · OpenVibe.Services](https://openvibe.services/docs/contracts/blog.changelog-entry)

# BlogChangelogEntry `blog.changelog-entry@2`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 2.0.0
- Owner: blog
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/blog/changelog-entry.v2.json`](/docs/contracts/blog.changelog-entry.json)

blog.changelog-entry@2: one shipped commit as OpenVibe.Blog's network changelog shows it (GET /api/v1/changelog, server/changelog.js). Every entry names what changed in plain words (plain, without its PR number or stage tag) and is tagged with a kind and up to three areas from Blog's fixed list; housekeeping (library pins, merges, test-only and docs-only changes) is kind internal and needs no model. The commit id, its GitHub URL and the pull request that shipped it stay available for the fold under the row.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `service` | string | yes | The site's registry id (live, chat, blog, …). | - `pattern ^[a-z][a-z0-9-]{0,39}$` |
| `repo` | string | yes | The GitHub repository the commit shipped from, owner/name. | - `pattern ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$` |
| `sha` | string | yes |  | - `pattern ^[0-9a-f]{7,40}$` |
| `short` | string | yes | The first seven characters of sha. | - `pattern ^[0-9a-f]{7}$` |
| `subject` | string | yes | The commit message's first line, as written. | - `minLength 1`<br>- `maxLength 240` |
| `plain` | string | yes | The subject in plain words: the PR number and stage tag removed, no other claim added. | - `minLength 1`<br>- `maxLength 240` |
| `kind` | enum | yes | new: something a person can now do; better: an existing thing improved; fixed: a defect repaired; internal: housekeeping with nothing for a person to notice. | - `one of "new", "better", "fixed", "internal"` |
| `areas` | array of enum | yes | One to three of Blog's fixed areas; empty only for kind internal. | - `maxItems 3`<br>- `unique items`<br>- `items: one of "phone", "chat", "go-live", "video", "menu", "accessibility", "speed", "sign-in", "wallet", "ai", "search", "files", "pictures", "games", "design", "developer", "machines", "money", "privacy", "moderation", "notifications", "feed", "wiki", "blog", "community", "meme", "shop", "tools", "exchange", "git"` |
| `author` | string \| null |  |  | - `maxLength 80` |
| `committed_at` | string \| null |  |  | - `format date-time` |
| `deployed_at` | string | yes | When the release carrying the commit was seen deployed. | - `format date-time` |
| `major` | boolean |  | True when the release was large or named as major; the hints a patch notes post highlights. |  |
| `url` | string | yes | The commit on GitHub. | - `pattern ^https://github.com/`<br>- `maxLength 2000` |
| `post_id` | string \| null |  | The patch notes post that carried it; null while pending and for imported history. | - `pattern ^pst_[0-9A-HJKMNP-TV-Z]{26}$` |
| `pr` | integer \| null |  | The pull request the subject names, when it names one. | - `minimum 1` |
| `pr_url` | string \| null |  |  | - `pattern ^https://github.com/`<br>- `maxLength 2000` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: chat-scroll-fix

~~~~
{
  "service": "chat",
  "repo": "OpenVibers/OpenVibe.Chat",
  "sha": "3d2c1b0a9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "short": "3d2c1b0",
  "subject": "Fix scroll jump when a message arrives while reading history (#361)",
  "plain": "Fix the chat jumping to the bottom when a message arrives while you read history",
  "kind": "fixed",
  "areas": [
    "chat",
    "accessibility"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-08T09:15:00.000Z",
  "deployed_at": "2026-11-08T11:00:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Chat/commit/3d2c1b0a9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "post_id": null,
  "pr": 361,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Chat/pull/361"
}
~~~~

Valid: devblog-card

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "plain": "The Recent Changes card now shows the newest devblog post with its art",
  "kind": "new",
  "areas": [
    "menu",
    "feed"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

Valid: housekeeping

~~~~
{
  "service": "network",
  "repo": "OpenVibers/OpenVibe.Network",
  "sha": "9c4f2a10b3d5e7f90123456789abcdef01234567",
  "short": "9c4f2a1",
  "subject": "openvibe-shared v4.175.0 (was v4.173.0) (#401)",
  "plain": "Pin openvibe-shared 4.175.0 (was 4.173.0)",
  "kind": "internal",
  "areas": [],
  "author": null,
  "committed_at": null,
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Network/commit/9c4f2a10b3d5e7f90123456789abcdef01234567",
  "post_id": null,
  "pr": null,
  "pr_url": null
}
~~~~

Rejected: bad-kind

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "plain": "The Recent Changes card now shows the newest devblog post with its art",
  "kind": "improvement",
  "areas": [
    "menu",
    "feed"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

Rejected: missing-plain

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "kind": "new",
  "areas": [
    "menu",
    "feed"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

Rejected: new-without-area

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "plain": "The Recent Changes card now shows the newest devblog post with its art",
  "kind": "new",
  "areas": [],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

Rejected: plain-with-pr

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "plain": "Show the newest devblog (#714)",
  "kind": "new",
  "areas": [
    "menu",
    "feed"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

Rejected: too-many-areas

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "plain": "The Recent Changes card now shows the newest devblog post with its art",
  "kind": "new",
  "areas": [
    "menu",
    "feed",
    "video",
    "chat"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

Rejected: unknown-area

~~~~
{
  "service": "live",
  "repo": "OpenVibers/OpenVibe.Live",
  "sha": "7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "short": "7b941a0",
  "subject": "Recent Changes card: show the newest devblog with its art (#714)",
  "plain": "The Recent Changes card now shows the newest devblog post with its art",
  "kind": "new",
  "areas": [
    "podcast"
  ],
  "author": "OpenVibers",
  "committed_at": "2026-11-09T18:40:12.000Z",
  "deployed_at": "2026-11-09T19:07:00.000Z",
  "major": false,
  "url": "https://github.com/OpenVibers/OpenVibe.Live/commit/7b941a0c1d2e3f405162738495a6b7c8d9e0f112",
  "post_id": "pst_01JAB2C3D4E5F6G7H8J9K0MNPQ",
  "pr": 714,
  "pr_url": "https://github.com/OpenVibers/OpenVibe.Live/pull/714"
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('blog.changelog-entry@2', value);   // { valid, errors: [{ path, message }] }
~~~~
