openvibers/openvibe.network Commits

Roadmap baseline reads the release layout, and ranks docs-only deploy drift low. collect-prod.sh took every /opt/openvibe.<svc> checkout's HEAD, so Live, which runs from current -> releases/<time>-<sha> (a git worktree of repo/) since 2026-09-27, showed the pre-release checkout 9f7f36c as deployed and 120 commits behind; a service with a current link now reports that release's commit (layout: release, release name), and Live reads b0cc2ef, what /release.json says. generate.js still reports every service behind origin/main, but when the commits between change only documentation and tests (README.md, STATUS.json, docs/*.md, the baseline's own files, test/, .github/, *.test.*) the row is low and names the files, since those ride the next deploy; drift in anything that runs stays medium. Regenerated 2026-09-28 03:40 UTC: 639 tables, 2453 routes, 112 call sites, 377 discrepancies, 6/7 exit criteria (EC7 waits for the host owner's hazard review); the 24 deploy rows are all low (the README/STATUS refreshes and Live's re-recorded N-1 fixtures), and Codes, deployed at 64d8feb (C-61), is current.

OP OpenVibers committed 28 Sept 2026 · 0b1dbdff3a · 13 files, +240 −233


Changes

ddiff --git a/docs/roadmap-baseline/01-services.md b/docs/roadmap-baseline/01-services.md
iindex 079189a9..777cd41c 100644
---- a/docs/roadmap-baseline/01-services.md
++++ b/docs/roadmap-baseline/01-services.md
@@@ -9,7 +9,7 @@ Deliverable 1: runtimes, ports, units, env files and repository state.
| Service | Repo | Stage | Ports | Units | Env file | Deployed | Databases |
|---|---|---|---|---|---|---|---|
| network | OpenVibe.Network | live | http 4000 | openvibe-network.service | /etc/openvibe/network.env | ddd87b6 | data/network.db |
--| live | OpenVibe.Live | live | http 3000, rtmp 1935/9935, mediasoup 11000-11300/udp, jsmpegRelayTls 9710-9789 | openvibe-live.socket, openvibe-live.service | /etc/openvibe/live.env | 9f7f36c | data/live.db, data/analytics.db, data/rs-companion.db |
++| live | OpenVibe.Live | live | http 3000, rtmp 1935/9935, mediasoup 11000-11300/udp, jsmpegRelayTls 9710-9789 | openvibe-live.socket, openvibe-live.service | /etc/openvibe/live.env | b0cc2ef | data/live.db, data/analytics.db, data/rs-companion.db |
| media | OpenVibe.Media | live | http 4100, rtpIngest 12000-12199/udp (127.0.0.1) | openvibe-media.service | /etc/openvibe/media.env | 6248363 | data/media.db |
| tools | OpenVibe.Tools | live | gateway 4001, maps 4010, food 4011, img 4012, yt 4013, audio 4014, text 4015, docs 4016 | openvibe-tools.service, openvibe-tools-maps.service, openvibe-tools-food.service, openvibe-tools-img.service, openvibe-tools-yt.service, openvibe-tools-audio.service, openvibe-tools-text.service, openvibe-tools-docs.service | /etc/openvibe/tools.env | e55469f | apps/<app>/data/analytics.db, apps/<app>/data/jobs.db |
| games | OpenVibe.Games | live | http 8000 | openvibe-games.service | /etc/openvibe/games.env | 51d8688 | data/world.db |
@@@ -31,7 +31,7 @@ Deliverable 1: runtimes, ports, units, env files and repository state.
| deals | OpenVibe.Deals | loopback | http 4840 | openvibe-deals.service | /etc/openvibe/deals.env | fa0582d | /var/lib/openvibe-deals/deals.db |
| coupons | OpenVibe.Coupons | loopback | http 4850 | openvibe-coupons.service | /etc/openvibe/coupons.env | 64835d2 | /var/lib/openvibe-coupons/coupons.db |
| trade | OpenVibe.Trade | loopback | http 4860 | openvibe-trade.service | /etc/openvibe/trade.env | 4658447 | /var/lib/openvibe-trade/trade.db |
--| codes | OpenVibe.Codes | live | http 4900 | openvibe-codes.service | /etc/openvibe/codes.env | d78de70 | /var/lib/openvibe-codes/codes.db |
++| codes | OpenVibe.Codes | live | http 4900 | openvibe-codes.service | /etc/openvibe/codes.env | 64d8feb | /var/lib/openvibe-codes/codes.db |
| host | OpenVibe.Host | loopback | http 4910 | openvibe-host.service, openvibe-backup.timer, openvibe-backup.service | /etc/openvibe/host.env | 2b63389 | /var/lib/openvibe-host-api/host.db |
| examples | OpenVibe.Examples | sample | | - | - | - | none |
@@@ -40,7 +40,7 @@ Deliverable 1: runtimes, ports, units, env files and repository state.
| Repo | HEAD | origin/main | Source files | LOC | Test files | CI | Routes | Tables | WS servers | Timers/jobs | TODO(contract) |
|---|---|---|---|---|---|---|---|---|---|---|---|
| OpenVibe.Live | 03f49b7 | 03f49b7 | 221 | 75126 | 158 | yes | 648 | 126 | 8 | 57 | 14 |
--| OpenVibe.Network | 5a50c12 | 5a50c12 | 103 | 21114 | 77 | yes | 355 | 70 | 0 | 14 | 3 |
++| OpenVibe.Network | c022f86 | c022f86 | 103 | 21114 | 77 | yes | 355 | 70 | 0 | 14 | 3 |
| OpenVibe.Shared | b5a9bd7 | b5a9bd7 | 58 | 15503 | 39 | yes | 2 | 2 | 0 | 8 | 0 |
| OpenVibe.Media | 14cac06 | 14cac06 | 79 | 20861 | 67 | yes | 144 | 34 | 0 | 16 | 0 |
| OpenVibe.Tools | 4f4ed6e | 4f4ed6e | 176 | 30522 | 61 | yes | 125 | 7 | 0 | 18 | 0 |
@@@ -63,7 +63,7 @@ Deliverable 1: runtimes, ports, units, env files and repository state.
| OpenVibe.Deals | 533450f | 533450f | 36 | 4980 | 17 | yes | 58 | 15 | 0 | 1 | 0 |
| OpenVibe.Coupons | b91cd79 | b91cd79 | 29 | 4289 | 16 | yes | 46 | 12 | 0 | 2 | 0 |
| OpenVibe.Trade | 273bce7 | 273bce7 | 37 | 4562 | 16 | yes | 7 | 10 | 0 | 2 | 0 |
--| OpenVibe.Codes | 7d6f65a | 7d6f65a | 32 | 5091 | 34 | yes | 107 | 7 | 0 | 0 | 0 |
++| OpenVibe.Codes | 64d8feb | 64d8feb | 32 | 5072 | 34 | yes | 107 | 7 | 0 | 0 | 0 |
| OpenVibe.Host | 6d2aaaa | 6d2aaaa | 68 | 11899 | 48 | yes | 57 | 11 | 0 | 1 | 0 |
| OpenVibe.Examples | 92eb7c3 | 92eb7c3 | 11 | 1604 | 16 | yes | 0 | 1 | 0 | 0 | 0 |
@@@ -89,11 +89,11 @@ LOC counts non-test source files in the scanned directories only (`server/`, `ap
| OpenVibe.Events | PUBLIC | alpha | 2026-09-28 | 550 KB | Durable events, subscriptions, delivery, retry, dead letters and replay for the network. |
| OpenVibe.Examples | PUBLIC | alpha | 2026-09-28 | 320 KB | Executable public integration examples, tested in CI against the platform. |
| OpenVibe.Extensions | PUBLIC | alpha | 2026-09-25 | 58 KB | First-party client surfaces for the network: the browser helper built on Coupons' public API with scoped, revocable credentials; later the kiosk/hardware companions and any desktop client (ADR-023). |
--| OpenVibe.Games | PUBLIC | stable | 2026-09-28 | 5596 KB | |
++| OpenVibe.Games | PUBLIC | stable | 2026-09-28 | 5693 KB | |
| OpenVibe.Host | PUBLIC | alpha | 2026-09-28 | 1384 KB | The network's deployment/control plane first; then isolated hosting for community sites, bots and mods. |
| OpenVibe.Live | PUBLIC | stable | 2026-09-28 | 9109 KB | |
| OpenVibe.Media | PUBLIC | beta | 2026-09-28 | 2022 KB | |
--| OpenVibe.Network | PUBLIC | stable | 2026-09-28 | 3416 KB | |
++| OpenVibe.Network | PUBLIC | stable | 2026-09-28 | 3471 KB | |
| OpenVibe.News | PUBLIC | alpha | 2026-09-28 | 466 KB | Source-backed stories: clustered coverage, cited summaries, perspectives and timelines. |
| OpenVibe.Publishing | PUBLIC | alpha | 2026-09-28 | 248 KB | Shared publishing packages (drafts, revisions, citations, SEO gate, feeds, structured data) for Wiki, Blog, News, Reviews, Deals, Coupons and Trade. Packages only, no authority. |
| OpenVibe.Realtime | PUBLIC | closed (no code) | 2026-09-25 | 16 KB | Archived: browser realtime runs in OpenVibe.Events (/realtime/stream). Decision record for ADR-005. |
ddiff --git a/docs/roadmap-baseline/03-routes.md b/docs/roadmap-baseline/03-routes.md
iindex c1e4f0cb..527d30d5 100644
---- a/docs/roadmap-baseline/03-routes.md
++++ b/docs/roadmap-baseline/03-routes.md
@@@ -2502,8 +2502,8 @@ Owner = the repository whose code answers the route; target = the authority it b
| ALL | /logout | server/auth/sso.js:233 | | keep |
| GET | /logout | server/auth/sso.js:224 | | keep |
| POST | /logout | server/auth/sso.js:232 | | keep |
--| GET | /manifests/validate | server/http/tools.js:175 | | keep |
--| POST | /manifests/validate | server/http/tools.js:176 | | keep |
++| GET | /manifests/validate | server/http/tools.js:170 | | keep |
++| POST | /manifests/validate | server/http/tools.js:171 | | keep |
| GET | /me | server/auth/sso.js:247 | | keep |
| GET | /oauth | server/http/tools.js:32 | | keep |
| GET | /oauth/test-callback | server/http/tools.js:68 | | keep |
@@@ -2570,9 +2570,9 @@ Owner = the repository whose code answers the route; target = the authority it b
| GET | /sitemap.xml | server/http/pages.js:274 | | keep |
| GET | /staff | server/http/pages.js:243 | | keep |
| POST | /staff/trust | server/http/pages.js:257 | | keep |
--| GET | /tools/webhooks | server/http/tools.js:146 | | keep |
--| POST | /tools/webhooks/sample | server/http/tools.js:152 | | keep |
--| POST | /tools/webhooks/verify | server/http/tools.js:147 | | keep |
++| GET | /tools/webhooks | server/http/tools.js:141 | | keep |
++| POST | /tools/webhooks/sample | server/http/tools.js:147 | | keep |
++| POST | /tools/webhooks/verify | server/http/tools.js:142 | | keep |
| GET | /updates | server/http/pages.js:88 | | keep |
## OpenVibe.Host
ddiff --git a/docs/roadmap-baseline/08-discrepancies.md b/docs/roadmap-baseline/08-discrepancies.md
iindex 458c4211..aae74abb 100644
---- a/docs/roadmap-baseline/08-discrepancies.md
++++ b/docs/roadmap-baseline/08-discrepancies.md
@@@ -2,35 +2,10 @@
> Generated by `scripts/roadmap-baseline/generate.js`. Do not edit by hand; edit `data/*.json` or the extractor and regenerate.
--Deliverable 7. Snapshot of openvibe-oregon taken 2026-09-28 03:25 UTC compared with the local checkouts. `unknown` rows are things this environment cannot see.
++Deliverable 7. Snapshot of openvibe-oregon taken 2026-09-28 03:31 UTC compared with the local checkouts. `unknown` rows are things this environment cannot see.
| Severity | Area | Subject | Detail |
|---|---|---|---|
--| medium | deploy | ai | deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833 |
--| medium | deploy | billing | deployed 80f97aa is 1 commit(s) behind origin/main f24684b |
--| medium | deploy | blog | deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb |
--| medium | deploy | chat | deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3 |
--| medium | deploy | codes | deployed d78de70 is 1 commit(s) behind origin/main 7d6f65a |
--| medium | deploy | community | deployed 52d923a is 1 commit(s) behind origin/main 2da3501 |
--| medium | deploy | coupons | deployed 64835d2 is 1 commit(s) behind origin/main b91cd79 |
--| medium | deploy | deals | deployed fa0582d is 1 commit(s) behind origin/main 533450f |
--| medium | deploy | events | deployed f55f7eb is 1 commit(s) behind origin/main 19919ec |
--| medium | deploy | games | deployed 51d8688 is 1 commit(s) behind origin/main eb2d008 |
--| medium | deploy | host | deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa |
--| medium | deploy | live | deployed 9f7f36c is 120 commit(s) behind origin/main 03f49b7 |
--| medium | deploy | media | deployed 6248363 is 1 commit(s) behind origin/main 14cac06 |
--| medium | deploy | network | deployed ddd87b6 is 1 commit(s) behind origin/main 5a50c12 |
--| medium | deploy | news | deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43 |
--| medium | deploy | openre | deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a |
--| medium | deploy | reviews | deployed 1cff36b is 1 commit(s) behind origin/main c87b344 |
--| medium | deploy | search | deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8 |
--| medium | deploy | sites | deployed 32464ec is 1 commit(s) behind origin/main 304e8b1 |
--| medium | deploy | sources | deployed 351383e is 1 commit(s) behind origin/main 1670853 |
--| medium | deploy | tips | deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5 |
--| medium | deploy | tools | deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e |
--| medium | deploy | trade | deployed 4658447 is 1 commit(s) behind origin/main 273bce7 |
--| medium | deploy | vip | deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19 |
--| medium | deploy | wiki | deployed 32a26ef is 1 commit(s) behind origin/main 3302540 |
| low | database | /opt/openvibe.blog/data/blog.db | 401 KB, 20 tables, not a database the service opens (services.json): stale file or undeclared copy |
| low | database | /opt/openvibe.community/data/community.db | 258 KB, 21 tables, not a database the service opens (services.json): stale file or undeclared copy |
| low | database | /opt/openvibe.games/data/legacy-import/world-before-20260923T184930Z.db | 193 KB, 13 tables, not a database the service opens (services.json): stale file or undeclared copy |
@@@ -77,6 +52,30 @@ Deliverable 7. Snapshot of openvibe-oregon taken 2026-09-28 03:25 UTC compared w
| low | database | /var/lib/openvibe-community/community.pre-c24b-20260925T185400Z.db | 2.2 MB copy (backup, import snapshot or rehearsal) kept beside the service data |
| low | database | /var/lib/openvibe-community/community.pre-c24c-20260925T185425Z.db | 2.2 MB copy (backup, import snapshot or rehearsal) kept beside the service data |
| low | database | /var/lib/openvibe-community/community.pre-live-comments-20260923T191345Z.db | 2.0 MB copy (backup, import snapshot or rehearsal) kept beside the service data |
++| low | deploy | ai | deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | billing | deployed 80f97aa is 1 commit(s) behind origin/main f24684b; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | blog | deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | chat | deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | community | deployed 52d923a is 1 commit(s) behind origin/main 2da3501; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | coupons | deployed 64835d2 is 1 commit(s) behind origin/main b91cd79; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | deals | deployed fa0582d is 1 commit(s) behind origin/main 533450f; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | events | deployed f55f7eb is 1 commit(s) behind origin/main 19919ec; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | games | deployed 51d8688 is 1 commit(s) behind origin/main eb2d008; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | host | deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa; only documentation and tests changed (README.md, STATUS.json, docs/deploy-strategies.md) |
++| low | deploy | live | deployed b0cc2ef is 1 commit(s) behind origin/main 03f49b7; only documentation and tests changed (test/fixtures/n-1/client.json, test/fixtures/n-1/worker.json) |
++| low | deploy | media | deployed 6248363 is 1 commit(s) behind origin/main 14cac06; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | network | deployed ddd87b6 is 2 commit(s) behind origin/main c022f86; only documentation and tests changed (README.md, STATUS.json, docs/roadmap-baseline/01-services.md and 17 more) |
++| low | deploy | news | deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | openre | deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | reviews | deployed 1cff36b is 1 commit(s) behind origin/main c87b344; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | search | deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | sites | deployed 32464ec is 1 commit(s) behind origin/main 304e8b1; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | sources | deployed 351383e is 1 commit(s) behind origin/main 1670853; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | tips | deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | tools | deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | trade | deployed 4658447 is 1 commit(s) behind origin/main 273bce7; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | vip | deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19; only documentation and tests changed (README.md, STATUS.json) |
++| low | deploy | wiki | deployed 32a26ef is 1 commit(s) behind origin/main 3302540; only documentation and tests changed (README.md, STATUS.json) |
| low | env | OpenRe.Stream:OPENRE_SECRETS_KEY_PREVIOUS | secret-named variable read by code but not set in the service env file: verify it is optional or has no hardcoded fallback |
| low | env | OpenVibe.Billing:CCBILL_WEBHOOK_SECRET | secret-named variable read by code but not set in the service env file: verify it is optional or has no hardcoded fallback |
| low | env | OpenVibe.Billing:NOWPAYMENTS_API_KEY | secret-named variable read by code but not set in the service env file: verify it is optional or has no hardcoded fallback |
ddiff --git a/docs/roadmap-baseline/09-d-status.md b/docs/roadmap-baseline/09-d-status.md
iindex a61f7716..668703a9 100644
---- a/docs/roadmap-baseline/09-d-status.md
++++ b/docs/roadmap-baseline/09-d-status.md
@@@ -26,7 +26,7 @@ Deliverable 8, derived from the [requirement ledger](requirement-ledger.md) (as
| D42 | Shared component architecture | partial | **partial** | D42 partial | W2, Track R | yes | 25 repos pin a tagged openvibe-shared release (latest v1.23.1): OpenRe.Stream v1.22.0, AI v1.22.0, Billing v1.22.0, Blog v1.22.0, Chat v1.22.0, Codes v1.22.0, Community v1.22.0, Coupons v1.22.0, Deals v1.22.0, Events v1.22.0, Games v1.23.0, Host v1.22.0, Live v1.23.1, Media v1.22.0, Network v1.22.0, News v1.22.0, Reviews v1.22.0, Search v1.22.0, Sites v1.23.0, Sources v1.22.0, Tips v1.22.0, Tools v1.23.0, Trade v1.22.0, VIP v1.22.0, Wiki v1.22.0; 31 manifests unpinned or behind: OpenRe.Stream (v1.22.0), AI (v1.22.0), Billing (v1.22.0), Blog (v1.22.0), Chat (v1.22.0), Codes (v1.22.0), Community (v1.22.0), Coupons (v1.22.0), Deals (v1.22.0), Events (v1.22.0), Games/apps/server (v1.23.0), Host (v1.22.0), Media (v1.22.0), Network (v1.22.0), News (v1.22.0), Reviews (v1.22.0), Search (v1.22.0), Sites (v1.23.0), Sources (v1.22.0), Tips (v1.22.0), Tools/apps/audio (v1.23.0), Tools/apps/docs (v1.23.0), Tools/apps/food (v1.23.0), Tools/apps/gateway (v1.23.0), Tools/apps/img (v1.23.0), Tools/apps/maps (v1.23.0), Tools/apps/text (v1.23.0), Tools/apps/yt (v1.23.0), Trade (v1.22.0), VIP (v1.22.0), Wiki (v1.22.0) |
| D43 | Safe active-client updates | absent | **partial** | D43 partial | Track R | yes | - |
| D44 | Crawlable component rendering | built | **partial** | D44 partial | Track R (preserve) | yes | - |
--| D45 | Release compatibility and recovery | absent | **partial** | D45 partial | Track R, W22 | yes | 25 service(s) not running origin/main |
++| D45 | Release compatibility and recovery | absent | **partial** | D45 partial | Track R, W22 | yes | 24 service(s) not running origin/main |
| D46 | Update observability and acceptance | absent | **partial** | D46 partial | Track R, Track O | yes | 27 of 27 scanned repos have .github/workflows |
Families: 0 met, 21 partial, 0 not met, 1 blocked on owner (of 22). Requirements: 3 met, 36 partial, 0 not met, 7 blocked on owner (of 46); 46 verified. At Wave 0 the same 22 families were 3 built, 11 partial, 8 absent.
ddiff --git a/docs/roadmap-baseline/10-hazards.md b/docs/roadmap-baseline/10-hazards.md
iindex 3993b0ff..6af1a0eb 100644
---- a/docs/roadmap-baseline/10-hazards.md
++++ b/docs/roadmap-baseline/10-hazards.md
@@@ -18,7 +18,7 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr
| H10 | Commit identity | medium | partial | **needed** | Every contributor | all | Per-repo git config user.email = [email protected]; every new commit follows it. Older history keeps some assistant trailers. | main history violates the rule in: Live (238 commits with assistant trailers); Network (14 commits with assistant trailers); Media (30 commits with assistant trailers); Tools (9 commits with assistant trailers) |
| H11 | analytics_events grows without pruning | medium | mitigated | - | OpenVibe.Shared maintainers (openvibe-shared/analytics.js) | Track O / ADR-021 - before any schema wave touching Live or Network | ADR-021: no IP, user id or city stored; raw analytics events are pruned after 30 days on a schedule in Live (nightly job), Tools (timer) and Network (openvibe-shared analytics retention.schedulePrune since 9bbd90f), rollups kept. | largest analytics stores: live/shared/data/analytics.db 525.4 MB; network/data/network.db 302.4 MB; tools/apps/audio/data/analytics.db 36.7 MB; tools/apps/text/data/analytics.db 5.9 MB |
| H12 | No Cloudflare cache-purge step after deploys | low | blocked-on-owner | **needed** | Platform operator | W21 / Track I | Cache Rules "browser_ttl respect_origin" on every openvibe.* zone and openre.stream (2026-09-23) make the edge follow origin max-age; Search has a purge queue that stays inert until a purge-scoped token exists (CLOUDFLARE_PURGE_TOKEN). | CLOUDFLARE_PURGE_TOKEN unset in search.env |
--| H13 | Production drifts from main | medium | open | - | Platform operator | W0 (checklist) / W21 (release manifests) | Deploy or record why each lagging service is held back. | ai: deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833; billing: deployed 80f97aa is 1 commit(s) behind origin/main f24684b; blog: deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb; chat: deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3; codes: deployed d78de70 is 1 commit(s) behind origin/main 7d6f65a; community: deployed 52d923a is 1 commit(s) behind origin/main 2da3501; coupons: deployed 64835d2 is 1 commit(s) behind origin/main b91cd79; deals: deployed fa0582d is 1 commit(s) behind origin/main 533450f; events: deployed f55f7eb is 1 commit(s) behind origin/main 19919ec; games: deployed 51d8688 is 1 commit(s) behind origin/main eb2d008; host: deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa; live: deployed 9f7f36c is 120 commit(s) behind origin/main 03f49b7; media: deployed 6248363 is 1 commit(s) behind origin/main 14cac06; network: deployed ddd87b6 is 1 commit(s) behind origin/main 5a50c12; news: deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43; openre: deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a; reviews: deployed 1cff36b is 1 commit(s) behind origin/main c87b344; search: deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8; sites: deployed 32464ec is 1 commit(s) behind origin/main 304e8b1; sources: deployed 351383e is 1 commit(s) behind origin/main 1670853; tips: deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5; tools: deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e; trade: deployed 4658447 is 1 commit(s) behind origin/main 273bce7; vip: deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19; wiki: deployed 32a26ef is 1 commit(s) behind origin/main 3302540 |
++| H13 | Production drifts from main | medium | open | - | Platform operator | W0 (checklist) / W21 (release manifests) | Deploy or record why each lagging service is held back. | ai: deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833; only documentation and tests changed (README.md, STATUS.json); billing: deployed 80f97aa is 1 commit(s) behind origin/main f24684b; only documentation and tests changed (README.md, STATUS.json); blog: deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb; only documentation and tests changed (README.md, STATUS.json); chat: deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3; only documentation and tests changed (README.md, STATUS.json); community: deployed 52d923a is 1 commit(s) behind origin/main 2da3501; only documentation and tests changed (README.md, STATUS.json); coupons: deployed 64835d2 is 1 commit(s) behind origin/main b91cd79; only documentation and tests changed (README.md, STATUS.json); deals: deployed fa0582d is 1 commit(s) behind origin/main 533450f; only documentation and tests changed (README.md, STATUS.json); events: deployed f55f7eb is 1 commit(s) behind origin/main 19919ec; only documentation and tests changed (README.md, STATUS.json); games: deployed 51d8688 is 1 commit(s) behind origin/main eb2d008; only documentation and tests changed (README.md, STATUS.json); host: deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa; only documentation and tests changed (README.md, STATUS.json, docs/deploy-strategies.md); live: deployed b0cc2ef is 1 commit(s) behind origin/main 03f49b7; only documentation and tests changed (test/fixtures/n-1/client.json, test/fixtures/n-1/worker.json); media: deployed 6248363 is 1 commit(s) behind origin/main 14cac06; only documentation and tests changed (README.md, STATUS.json); network: deployed ddd87b6 is 2 commit(s) behind origin/main c022f86; only documentation and tests changed (README.md, STATUS.json, docs/roadmap-baseline/01-services.md and 17 more); news: deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43; only documentation and tests changed (README.md, STATUS.json); openre: deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a; only documentation and tests changed (README.md, STATUS.json); reviews: deployed 1cff36b is 1 commit(s) behind origin/main c87b344; only documentation and tests changed (README.md, STATUS.json); search: deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8; only documentation and tests changed (README.md, STATUS.json); sites: deployed 32464ec is 1 commit(s) behind origin/main 304e8b1; only documentation and tests changed (README.md, STATUS.json); sources: deployed 351383e is 1 commit(s) behind origin/main 1670853; only documentation and tests changed (README.md, STATUS.json); tips: deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5; only documentation and tests changed (README.md, STATUS.json); tools: deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e; only documentation and tests changed (README.md, STATUS.json); trade: deployed 4658447 is 1 commit(s) behind origin/main 273bce7; only documentation and tests changed (README.md, STATUS.json); vip: deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19; only documentation and tests changed (README.md, STATUS.json); wiki: deployed 32a26ef is 1 commit(s) behind origin/main 3302540; only documentation and tests changed (README.md, STATUS.json) |
| H14 | Dead and backup database files on the production host | low | open | **needed** | Live maintainers | W0 | Confirm no code opens them, then delete the empty files; move copies (backups, import snapshots, rehearsal databases) to /var/backups/openvibe with a retention date. | blog/data/blog.db, community/data/community.db, games/data/legacy-import/world-before-20260923T184930Z.db, live/shared/data/analytics.db, live/shared/data/backups/analytics-pre-adr021-2026-09-23.db, live/shared/data/backups/live-20260926-072748.db, live/shared/data/backups/live-20260926-095352.db, live/shared/data/backups/live-pre-643a2e6.db, live/shared/data/backups/live-pre-identity-contract-20260928-001702Z.db, live/shared/data/hobo.db, live/shared/data/live-before-rs-slots-20260924T0153Z.db, live/shared/data/live.db, live/shared/data/openvibe.db, live/shared/data/rs-companion.db, media/data/backups/owner-subject-20260923.media.db, media/data/reports/h15-repair-applied-20260925.media.db, network/data/backups/network-pre-creator-analytics-20260926.db, network/data/backups/network-pre-follows-20260926.db, network/data/network-pre-refresh-hash-2026-09-24.db, network/data/network-pre-secrets-2026-09-24.db, tips/data/tips.db, tools/apps/audio/data/guard.db, tools/apps/docs/data/guard.db, tools/apps/food/data/guard.db, tools/apps/gateway/data/guard.db, tools/apps/gateway/data/token-revocations.db, tools/apps/img/data/guard.db, tools/apps/maps/data/guard.db, tools/apps/text/data/guard.db, tools/apps/yt/data/guard.db, tools/backups/analytics-2026-09-23/audio.analytics.db, tools/backups/analytics-2026-09-23/docs.analytics.db, tools/backups/analytics-2026-09-23/food.analytics.db, tools/backups/analytics-2026-09-23/img.analytics.db, tools/backups/analytics-2026-09-23/maps.analytics.db, tools/backups/analytics-2026-09-23/text.analytics.db, tools/backups/analytics-2026-09-23/yt.analytics.db, billing/live-snapshot-202609230121.db, chat/live-snap-a.db, chat/live-snap-b.db, chat/live-snapshot-0159.db, chat/rehearsal.db, community/community.pre-c24-20260925T185117Z.db, community/community.pre-c24b-20260925T185400Z.db, community/community.pre-c24c-20260925T185425Z.db, community/community.pre-live-comments-20260923T191345Z.db |
| H15 | Media objects with no good copy | medium | blocked-on-owner | **needed** | Media maintainers | W4 (repair) / W22 (DR drills) | Scheduled copy verification now runs inside Media and reports through /api/ready (object_copies); the 6 objects are marked degraded. Each needs a decision: re-upload from a surviving source, or mark it unrecoverable and tell its owner. | - |
| H16 | Off-host backups are unreadable without the backup key, which lives only on the host | high | blocked-on-owner | **needed** | Production-host owner | W22 | Escrow the key offline (password manager or paper), record its key id (`ovhost offsite check`) next to it, and test a restore from the bucket with the escrowed copy. | openvibe-backup.timer is active/waiting |
ddiff --git a/docs/roadmap-baseline/README.md b/docs/roadmap-baseline/README.md
iindex dde72fb2..a1c27ebb 100644
---- a/docs/roadmap-baseline/README.md
++++ b/docs/roadmap-baseline/README.md
@@@ -2,7 +2,7 @@
The audit baseline from the OpenVibe development roadmap (Wave 0; section 12 items 1-3): what exists across the estate, who owns each piece of data today and who should, what production looks like next to the repos, and which hazards constrain later waves. Every file here except `data/*.json` is generated.
--Source commits: Live `03f49b7`, Network `5a50c12`, Shared `b5a9bd7`, Media `14cac06`, Tools `4f4ed6e`, Community `2da3501`, Games `eb2d008`, Sites `304e8b1`, Events `19919ec`, Chat `d87c8d3`, OpenRe.Stream `c77ec2a`, Billing `f24684b`, Tips `13986b5`, VIP `95b3e19`, AI `6c8b833`, Search `e8511d8`, Sources `1670853`, Wiki `3302540`, Blog `8a7f8eb`, News `97dae43`, Reviews `c87b344`, Deals `533450f`, Coupons `b91cd79`, Trade `273bce7`, Codes `7d6f65a`, Host `6d2aaaa`, Examples `92eb7c3`. Production snapshot: openvibe-oregon, 2026-09-28.
++Source commits: Live `03f49b7`, Network `c022f86`, Shared `b5a9bd7`, Media `14cac06`, Tools `4f4ed6e`, Community `2da3501`, Games `eb2d008`, Sites `304e8b1`, Events `19919ec`, Chat `d87c8d3`, OpenRe.Stream `c77ec2a`, Billing `f24684b`, Tips `13986b5`, VIP `95b3e19`, AI `6c8b833`, Search `e8511d8`, Sources `1670853`, Wiki `3302540`, Blog `8a7f8eb`, News `97dae43`, Reviews `c87b344`, Deals `533450f`, Coupons `b91cd79`, Trade `273bce7`, Codes `64d8feb`, Host `6d2aaaa`, Examples `92eb7c3`. Production snapshot: openvibe-oregon, 2026-09-28.
## Deliverables
@@@ -14,7 +14,7 @@ Source commits: Live `03f49b7`, Network `5a50c12`, Shared `b5a9bd7`, Media `14ca
| 4 | [05-realtime-and-jobs.md](05-realtime-and-jobs.md) | WebSocket servers and paths, non-HTTP protocols, background jobs |
| 5 | [06-secrets.md](06-secrets.md) | auth mechanisms and secret names (no values) |
| 6 | [07-ownership.md](07-ownership.md) | current vs target data ownership |
--| 7 | [08-discrepancies.md](08-discrepancies.md) | 378 production-vs-repo items |
++| 7 | [08-discrepancies.md](08-discrepancies.md) | 377 production-vs-repo items |
| 8 | [09-d-status.md](09-d-status.md) | D01-D46 family status, derived from the requirement ledger (families: 0 met, 21 partial, 0 not met, 1 blocked on owner) |
| 9 | [10-hazards.md](10-hazards.md) | 18 hazards with owners, mitigations and waves; 10 need the owner's review |
| 10 | [requirement-ledger.md](requirement-ledger.md), [requirement-ledger.json](requirement-ledger.json) | D01-D46 with acceptance artifacts (roadmap §22.4/§25): 3 met, 36 partial, 0 not met, 7 blocked on owner |
ddiff --git a/docs/roadmap-baseline/data/github.json b/docs/roadmap-baseline/data/github.json
iindex 84c31e08..fc4aa3cb 100644
---- a/docs/roadmap-baseline/data/github.json
++++ b/docs/roadmap-baseline/data/github.json
@@@ -1,6 +1,6 @@
{
"owner": "OpenVibers",
-- "collectedAt": "2026-09-28T03:25:56.178Z",
++ "collectedAt": "2026-09-28T03:32:40.497Z",
"repos": [
{
"description": "AlexFrison.net",
@@@ -308,7 +308,7 @@
"diskUsage": 814,
"isArchived": false,
"name": "OpenVibe.Codes",
-- "pushedAt": "2026-09-28T03:20:37Z",
++ "pushedAt": "2026-09-28T03:29:24Z",
"visibility": "PUBLIC",
"defaultBranch": "main",
"status": {
@@@ -323,7 +323,7 @@
"contracts": "openvibe-contracts v0.53.0",
"packages": [
"openvibe-contracts v0.53.0",
-- "openvibe-sdk v0.12.0",
++ "openvibe-sdk v0.13.0",
"openvibe-shared v1.22.0"
],
"summary": "Deployed and public since 2026-09-23: https://openvibe.codes is served by this portal (deployed with `sudo ovhost deploy codes`, unit openvibe-codes on 127.0.0.1:4900 behind nginx), and the domain left OpenVibe.Sites. Sign-in uses the registered Network OAuth client `codes` (PKCE S256); the principal `codes` holds events.event.publish and the Events relay is configured. On 2026-09-23 production held 0 manifests, 0 releases and 0 playground runs. The external-developer path (account, project, sandbox app, grants, Media upload, app events) was run once on production on 2026-09-23 with public endpoints and curl, not through these playgrounds; that check is not committed to a repository or CI.",
@@@ -337,7 +337,7 @@
"Scope editor offering only capabilities apps can be granted (public, or partner when in the allowance)",
"Docs generated at boot from the pinned openvibe-contracts and openvibe-sdk: contracts with field tables and fixtures, capability catalog, event types, SDK reference; service registry read live from Network with its health",
"OAuth callback helper and a test callback that never exchanges the code",
-- "Webhook tester for signature v1 and v2 (server or in-browser): decides as a receiver requiring v2 does, shows the timestamp's age and the ±300 s window, v1 shown but never deciding; signed sample deliveries carry v1, X-OpenVibe-Timestamp and v2",
++ "Webhook tester for signature v2 (server or in-browser): decides as a receiver requiring v2 does and shows the timestamp's age and the ±300 s window; v1 was retired on 2026-09-28 and has no field; signed sample deliveries carry X-OpenVibe-Timestamp and v2 only",
"Playgrounds (Media upload with media.object.upload, Events publish with events.app.publish) that run with the app's own token and refuse without the grant",
"App and mod manifest validation; release metadata (draft, publish, deprecate, revoke) with codes.app.* events through the SDK outbox; trust tiers per ADR-013 (unreviewed, reviewed, first-party) as staff-set metadata, older names migrated at boot",
"Policy pages rendered from the published ADRs; licensing read from package metadata; governance pages (code of conduct, contributing, contributor ladder, moderation policy) rendered from the repository's Markdown",
@@@ -364,7 +364,7 @@
"secrets shown once, never stored or logged",
"scope editor offering only grantable capabilities",
"docs generated from the pinned contracts and SDK",
-- "OAuth helper and webhook tester (signature v1 and v2)",
++ "OAuth helper and webhook tester (signature v2)",
"grant-respecting Media and Events playgrounds",
"app and mod manifest validation and release metadata with codes.app.* events",
"ADR-013 trust tiers",
@@@ -714,7 +714,7 @@
},
{
"description": "",
-- "diskUsage": 5596,
++ "diskUsage": 5693,
"isArchived": false,
"name": "OpenVibe.Games",
"pushedAt": "2026-09-28T03:20:51Z",
@@@ -913,10 +913,10 @@
},
{
"description": "",
-- "diskUsage": 3416,
++ "diskUsage": 3471,
"isArchived": false,
"name": "OpenVibe.Network",
-- "pushedAt": "2026-09-28T03:20:56Z",
++ "pushedAt": "2026-09-28T03:27:59Z",
"visibility": "PUBLIC",
"defaultBranch": "main",
"status": {
ddiff --git a/docs/roadmap-baseline/data/prod-snapshot.json b/docs/roadmap-baseline/data/prod-snapshot.json
iindex b994bb30..99e3d256 100644
---- a/docs/roadmap-baseline/data/prod-snapshot.json
++++ b/docs/roadmap-baseline/data/prod-snapshot.json
@@@ -1,6 +1,6 @@
{
"host": "openvibe-oregon",
-- "collectedAt": "2026-09-28T03:25:35.860Z",
++ "collectedAt": "2026-09-28T03:31:00.238Z",
"deployments": {
"ai": {
"path": "/opt/openvibe.ai",
@@@ -24,8 +24,8 @@
},
"codes": {
"path": "/opt/openvibe.codes",
-- "sha": "d78de7052c08dc38c6e2c400a0b63a1b00793f1f",
-- "committedAt": "2026-09-27T18:55:28-07:00"
++ "sha": "64d8feb1ac841c01f93e197b6a20eb07a09ef428",
++ "committedAt": "2026-09-27T20:27:52-07:00"
},
"community": {
"path": "/opt/openvibe.community",
@@@ -59,8 +59,10 @@
},
"live": {
"path": "/opt/openvibe.live",
-- "sha": "9f7f36c7d492266f27484c659ed84a7481803345",
-- "committedAt": "2026-09-23T22:50:15-07:00"
++ "layout": "release",
++ "release": "20260928-032420-b0cc2ef4",
++ "sha": "b0cc2ef4f8a57c9624b88af64a6aa4bd1e425279",
++ "committedAt": "2026-09-27T19:58:34-07:00"
},
"media": {
"path": "/opt/openvibe.media",
ddiff --git a/docs/roadmap-baseline/inventory.json b/docs/roadmap-baseline/inventory.json
iindex 49594679..4b28e937 100644
---- a/docs/roadmap-baseline/inventory.json
++++ b/docs/roadmap-baseline/inventory.json
@@@ -1,7 +1,7 @@
{
"generatedFrom": {
"OpenVibe.Live": "03f49b7716b7cee1cce8a44e7155aeb96a67d004",
-- "OpenVibe.Network": "5a50c12a83f6501aacd663f15d3c06c718a4c83a",
++ "OpenVibe.Network": "c022f86236f3e8251c924fae6c98494658b795a4",
"OpenVibe.Shared": "b5a9bd77171fcf75f42ff33fe86b7ad06baac1c8",
"OpenVibe.Media": "14cac06886649848c332cfa564aa6b3594ea09bc",
"OpenVibe.Tools": "4f4ed6e8f3f3c8e1a83dd644dd3c0659a7bccce4",
@@@ -24,13 +24,13 @@
"OpenVibe.Deals": "533450f9cc4a358ba50f353f06826ec3611b4ddc",
"OpenVibe.Coupons": "b91cd795e8ee4a3e49317a6e3cb000fa92da9325",
"OpenVibe.Trade": "273bce7b1b8771037bc2a660fa8784dc1aa049a7",
-- "OpenVibe.Codes": "7d6f65ac198d95f70ac840c24d03d1407affb7a9",
++ "OpenVibe.Codes": "64d8feb1ac841c01f93e197b6a20eb07a09ef428",
"OpenVibe.Host": "6d2aaaa630e29d2bfd261a7f75cbbbaa2b8c1d46",
"OpenVibe.Examples": "92eb7c3b0f50fea9f76086ed3eeda3664de93494"
},
"prodSnapshot": {
"host": "openvibe-oregon",
-- "collectedAt": "2026-09-28T03:25:35.860Z"
++ "collectedAt": "2026-09-28T03:31:00.238Z"
},
"repos": [
{
@@@ -9302,10 +9302,10 @@
"service": "network",
"present": true,
"git": {
-- "head": "5a50c12a83f6501aacd663f15d3c06c718a4c83a",
++ "head": "c022f86236f3e8251c924fae6c98494658b795a4",
"branch": "main",
-- "originMain": "5a50c12a83f6501aacd663f15d3c06c718a4c83a",
-- "committedAt": "2026-09-27T20:18:27-07:00"
++ "originMain": "c022f86236f3e8251c924fae6c98494658b795a4",
++ "committedAt": "2026-09-27T20:27:57-07:00"
},
"sourceFiles": 103,
"loc": 21114,
@@@ -35668,13 +35668,13 @@
"service": "codes",
"present": true,
"git": {
-- "head": "7d6f65ac198d95f70ac840c24d03d1407affb7a9",
++ "head": "64d8feb1ac841c01f93e197b6a20eb07a09ef428",
"branch": "main",
-- "originMain": "7d6f65ac198d95f70ac840c24d03d1407affb7a9",
-- "committedAt": "2026-09-27T20:00:39-07:00"
++ "originMain": "64d8feb1ac841c01f93e197b6a20eb07a09ef428",
++ "committedAt": "2026-09-27T20:27:52-07:00"
},
"sourceFiles": 32,
-- "loc": 5091,
++ "loc": 5072,
"tables": [
{
"table": "manifests",
@@@ -36074,7 +36074,7 @@
"method": "GET",
"path": "/manifests/validate",
"file": "server/http/tools.js",
-- "line": 175,
++ "line": 170,
"target": "OpenVibe.Codes",
"disposition": "keep",
"wave": "-",
@@@ -36084,7 +36084,7 @@
"method": "POST",
"path": "/manifests/validate",
"file": "server/http/tools.js",
-- "line": 176,
++ "line": 171,
"target": "OpenVibe.Codes",
"disposition": "keep",
"wave": "-",
@@@ -36754,7 +36754,7 @@
"method": "GET",
"path": "/tools/webhooks",
"file": "server/http/tools.js",
-- "line": 146,
++ "line": 141,
"target": "OpenVibe.Codes",
"disposition": "keep",
"wave": "-",
@@@ -36764,7 +36764,7 @@
"method": "POST",
"path": "/tools/webhooks/sample",
"file": "server/http/tools.js",
-- "line": 152,
++ "line": 147,
"target": "OpenVibe.Codes",
"disposition": "keep",
"wave": "-",
@@@ -36774,7 +36774,7 @@
"method": "POST",
"path": "/tools/webhooks/verify",
"file": "server/http/tools.js",
-- "line": 147,
++ "line": 142,
"target": "OpenVibe.Codes",
"disposition": "keep",
"wave": "-",
@@@ -61769,156 +61769,6 @@
}
],
"discrepancies": [
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "ai",
-- "detail": "deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "billing",
-- "detail": "deployed 80f97aa is 1 commit(s) behind origin/main f24684b"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "blog",
-- "detail": "deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "chat",
-- "detail": "deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "codes",
-- "detail": "deployed d78de70 is 1 commit(s) behind origin/main 7d6f65a"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "community",
-- "detail": "deployed 52d923a is 1 commit(s) behind origin/main 2da3501"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "coupons",
-- "detail": "deployed 64835d2 is 1 commit(s) behind origin/main b91cd79"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "deals",
-- "detail": "deployed fa0582d is 1 commit(s) behind origin/main 533450f"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "events",
-- "detail": "deployed f55f7eb is 1 commit(s) behind origin/main 19919ec"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "games",
-- "detail": "deployed 51d8688 is 1 commit(s) behind origin/main eb2d008"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "host",
-- "detail": "deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "live",
-- "detail": "deployed 9f7f36c is 120 commit(s) behind origin/main 03f49b7"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "media",
-- "detail": "deployed 6248363 is 1 commit(s) behind origin/main 14cac06"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "network",
-- "detail": "deployed ddd87b6 is 1 commit(s) behind origin/main 5a50c12"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "news",
-- "detail": "deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "openre",
-- "detail": "deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "reviews",
-- "detail": "deployed 1cff36b is 1 commit(s) behind origin/main c87b344"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "search",
-- "detail": "deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "sites",
-- "detail": "deployed 32464ec is 1 commit(s) behind origin/main 304e8b1"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "sources",
-- "detail": "deployed 351383e is 1 commit(s) behind origin/main 1670853"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "tips",
-- "detail": "deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "tools",
-- "detail": "deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "trade",
-- "detail": "deployed 4658447 is 1 commit(s) behind origin/main 273bce7"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "vip",
-- "detail": "deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19"
-- },
-- {
-- "severity": "medium",
-- "area": "deploy",
-- "subject": "wiki",
-- "detail": "deployed 32a26ef is 1 commit(s) behind origin/main 3302540"
-- },
{
"severity": "low",
"area": "database",
@@@ -62195,6 +62045,150 @@
"subject": "/var/lib/openvibe-community/community.pre-live-comments-20260923T191345Z.db",
"detail": "2.0 MB copy (backup, import snapshot or rehearsal) kept beside the service data"
},
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "ai",
++ "detail": "deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "billing",
++ "detail": "deployed 80f97aa is 1 commit(s) behind origin/main f24684b; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "blog",
++ "detail": "deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "chat",
++ "detail": "deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "community",
++ "detail": "deployed 52d923a is 1 commit(s) behind origin/main 2da3501; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "coupons",
++ "detail": "deployed 64835d2 is 1 commit(s) behind origin/main b91cd79; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "deals",
++ "detail": "deployed fa0582d is 1 commit(s) behind origin/main 533450f; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "events",
++ "detail": "deployed f55f7eb is 1 commit(s) behind origin/main 19919ec; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "games",
++ "detail": "deployed 51d8688 is 1 commit(s) behind origin/main eb2d008; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "host",
++ "detail": "deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa; only documentation and tests changed (README.md, STATUS.json, docs/deploy-strategies.md)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "live",
++ "detail": "deployed b0cc2ef is 1 commit(s) behind origin/main 03f49b7; only documentation and tests changed (test/fixtures/n-1/client.json, test/fixtures/n-1/worker.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "media",
++ "detail": "deployed 6248363 is 1 commit(s) behind origin/main 14cac06; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "network",
++ "detail": "deployed ddd87b6 is 2 commit(s) behind origin/main c022f86; only documentation and tests changed (README.md, STATUS.json, docs/roadmap-baseline/01-services.md and 17 more)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "news",
++ "detail": "deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "openre",
++ "detail": "deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "reviews",
++ "detail": "deployed 1cff36b is 1 commit(s) behind origin/main c87b344; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "search",
++ "detail": "deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "sites",
++ "detail": "deployed 32464ec is 1 commit(s) behind origin/main 304e8b1; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "sources",
++ "detail": "deployed 351383e is 1 commit(s) behind origin/main 1670853; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "tips",
++ "detail": "deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "tools",
++ "detail": "deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "trade",
++ "detail": "deployed 4658447 is 1 commit(s) behind origin/main 273bce7; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "vip",
++ "detail": "deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19; only documentation and tests changed (README.md, STATUS.json)"
++ },
++ {
++ "severity": "low",
++ "area": "deploy",
++ "subject": "wiki",
++ "detail": "deployed 32a26ef is 1 commit(s) behind origin/main 3302540; only documentation and tests changed (README.md, STATUS.json)"
++ },
{
"severity": "low",
"area": "env",
@@@ -64048,7 +64042,7 @@
"shared.pins": "25 repos pin a tagged openvibe-shared release (latest v1.23.1): OpenRe.Stream v1.22.0, AI v1.22.0, Billing v1.22.0, Blog v1.22.0, Chat v1.22.0, Codes v1.22.0, Community v1.22.0, Coupons v1.22.0, Deals v1.22.0, Events v1.22.0, Games v1.23.0, Host v1.22.0, Live v1.23.1, Media v1.22.0, Network v1.22.0, News v1.22.0, Reviews v1.22.0, Search v1.22.0, Sites v1.23.0, Sources v1.22.0, Tips v1.22.0, Tools v1.23.0, Trade v1.22.0, VIP v1.22.0, Wiki v1.22.0",
"shared.drift": "31 manifests unpinned or behind: OpenRe.Stream (v1.22.0), AI (v1.22.0), Billing (v1.22.0), Blog (v1.22.0), Chat (v1.22.0), Codes (v1.22.0), Community (v1.22.0), Coupons (v1.22.0), Deals (v1.22.0), Events (v1.22.0), Games/apps/server (v1.23.0), Host (v1.22.0), Media (v1.22.0), Network (v1.22.0), News (v1.22.0), Reviews (v1.22.0), Search (v1.22.0), Sites (v1.23.0), Sources (v1.22.0), Tips (v1.22.0), Tools/apps/audio (v1.23.0), Tools/apps/docs (v1.23.0), Tools/apps/food (v1.23.0), Tools/apps/gateway (v1.23.0), Tools/apps/img (v1.23.0), Tools/apps/maps (v1.23.0), Tools/apps/text (v1.23.0), Tools/apps/yt (v1.23.0), Trade (v1.22.0), VIP (v1.22.0), Wiki (v1.22.0)",
"ci.repos": "27 of 27 scanned repos have .github/workflows",
-- "deploy.drift": "25 service(s) not running origin/main",
++ "deploy.drift": "24 service(s) not running origin/main",
"tests.OpenVibe.Live": "158 test files",
"tables.OpenVibe.Live": "126 tables",
"tables.OpenVibe.Live.target:OpenVibe.Live": "35 Live tables target OpenVibe.Live",
@@@ -64617,7 +64611,7 @@
"metrics": [
{
"key": "deploy.drift",
-- "value": "25 service(s) not running origin/main"
++ "value": "24 service(s) not running origin/main"
}
],
"members": [
@@@ -64835,7 +64829,7 @@
"status": "open",
"check": "deploy-drift",
"ownerReview": false,
-- "checkResult": "ai: deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833; billing: deployed 80f97aa is 1 commit(s) behind origin/main f24684b; blog: deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb; chat: deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3; codes: deployed d78de70 is 1 commit(s) behind origin/main 7d6f65a; community: deployed 52d923a is 1 commit(s) behind origin/main 2da3501; coupons: deployed 64835d2 is 1 commit(s) behind origin/main b91cd79; deals: deployed fa0582d is 1 commit(s) behind origin/main 533450f; events: deployed f55f7eb is 1 commit(s) behind origin/main 19919ec; games: deployed 51d8688 is 1 commit(s) behind origin/main eb2d008; host: deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa; live: deployed 9f7f36c is 120 commit(s) behind origin/main 03f49b7; media: deployed 6248363 is 1 commit(s) behind origin/main 14cac06; network: deployed ddd87b6 is 1 commit(s) behind origin/main 5a50c12; news: deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43; openre: deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a; reviews: deployed 1cff36b is 1 commit(s) behind origin/main c87b344; search: deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8; sites: deployed 32464ec is 1 commit(s) behind origin/main 304e8b1; sources: deployed 351383e is 1 commit(s) behind origin/main 1670853; tips: deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5; tools: deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e; trade: deployed 4658447 is 1 commit(s) behind origin/main 273bce7; vip: deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19; wiki: deployed 32a26ef is 1 commit(s) behind origin/main 3302540"
++ "checkResult": "ai: deployed 549bed0 is 1 commit(s) behind origin/main 6c8b833; only documentation and tests changed (README.md, STATUS.json); billing: deployed 80f97aa is 1 commit(s) behind origin/main f24684b; only documentation and tests changed (README.md, STATUS.json); blog: deployed 21d537c is 1 commit(s) behind origin/main 8a7f8eb; only documentation and tests changed (README.md, STATUS.json); chat: deployed 3aab730 is 1 commit(s) behind origin/main d87c8d3; only documentation and tests changed (README.md, STATUS.json); community: deployed 52d923a is 1 commit(s) behind origin/main 2da3501; only documentation and tests changed (README.md, STATUS.json); coupons: deployed 64835d2 is 1 commit(s) behind origin/main b91cd79; only documentation and tests changed (README.md, STATUS.json); deals: deployed fa0582d is 1 commit(s) behind origin/main 533450f; only documentation and tests changed (README.md, STATUS.json); events: deployed f55f7eb is 1 commit(s) behind origin/main 19919ec; only documentation and tests changed (README.md, STATUS.json); games: deployed 51d8688 is 1 commit(s) behind origin/main eb2d008; only documentation and tests changed (README.md, STATUS.json); host: deployed 2b63389 is 2 commit(s) behind origin/main 6d2aaaa; only documentation and tests changed (README.md, STATUS.json, docs/deploy-strategies.md); live: deployed b0cc2ef is 1 commit(s) behind origin/main 03f49b7; only documentation and tests changed (test/fixtures/n-1/client.json, test/fixtures/n-1/worker.json); media: deployed 6248363 is 1 commit(s) behind origin/main 14cac06; only documentation and tests changed (README.md, STATUS.json); network: deployed ddd87b6 is 2 commit(s) behind origin/main c022f86; only documentation and tests changed (README.md, STATUS.json, docs/roadmap-baseline/01-services.md and 17 more); news: deployed 8ab47a6 is 1 commit(s) behind origin/main 97dae43; only documentation and tests changed (README.md, STATUS.json); openre: deployed cf423e3 is 1 commit(s) behind origin/main c77ec2a; only documentation and tests changed (README.md, STATUS.json); reviews: deployed 1cff36b is 1 commit(s) behind origin/main c87b344; only documentation and tests changed (README.md, STATUS.json); search: deployed 8ed7667 is 1 commit(s) behind origin/main e8511d8; only documentation and tests changed (README.md, STATUS.json); sites: deployed 32464ec is 1 commit(s) behind origin/main 304e8b1; only documentation and tests changed (README.md, STATUS.json); sources: deployed 351383e is 1 commit(s) behind origin/main 1670853; only documentation and tests changed (README.md, STATUS.json); tips: deployed 1e6bfbb is 1 commit(s) behind origin/main 13986b5; only documentation and tests changed (README.md, STATUS.json); tools: deployed e55469f is 1 commit(s) behind origin/main 4f4ed6e; only documentation and tests changed (README.md, STATUS.json); trade: deployed 4658447 is 1 commit(s) behind origin/main 273bce7; only documentation and tests changed (README.md, STATUS.json); vip: deployed 0fbcbb5 is 1 commit(s) behind origin/main 95b3e19; only documentation and tests changed (README.md, STATUS.json); wiki: deployed 32a26ef is 1 commit(s) behind origin/main 3302540; only documentation and tests changed (README.md, STATUS.json)"
},
{
"id": "H14",
ddiff --git a/docs/roadmap-baseline/requirement-ledger.json b/docs/roadmap-baseline/requirement-ledger.json
iindex cbcf8e24..4b444ab5 100644
---- a/docs/roadmap-baseline/requirement-ledger.json
++++ b/docs/roadmap-baseline/requirement-ledger.json
@@@ -3,7 +3,7 @@
"asOf": "2026-09-23T20:30Z",
"generatedFrom": {
"OpenVibe.Live": "03f49b7716b7cee1cce8a44e7155aeb96a67d004",
-- "OpenVibe.Network": "5a50c12a83f6501aacd663f15d3c06c718a4c83a",
++ "OpenVibe.Network": "c022f86236f3e8251c924fae6c98494658b795a4",
"OpenVibe.Shared": "b5a9bd77171fcf75f42ff33fe86b7ad06baac1c8",
"OpenVibe.Media": "14cac06886649848c332cfa564aa6b3594ea09bc",
"OpenVibe.Tools": "4f4ed6e8f3f3c8e1a83dd644dd3c0659a7bccce4",
@@@ -26,13 +26,13 @@
"OpenVibe.Deals": "533450f9cc4a358ba50f353f06826ec3611b4ddc",
"OpenVibe.Coupons": "b91cd795e8ee4a3e49317a6e3cb000fa92da9325",
"OpenVibe.Trade": "273bce7b1b8771037bc2a660fa8784dc1aa049a7",
-- "OpenVibe.Codes": "7d6f65ac198d95f70ac840c24d03d1407affb7a9",
++ "OpenVibe.Codes": "64d8feb1ac841c01f93e197b6a20eb07a09ef428",
"OpenVibe.Host": "6d2aaaa630e29d2bfd261a7f75cbbbaa2b8c1d46",
"OpenVibe.Examples": "92eb7c3b0f50fea9f76086ed3eeda3664de93494"
},
"prodSnapshot": {
"host": "openvibe-oregon",
-- "collectedAt": "2026-09-28T03:25:35.860Z"
++ "collectedAt": "2026-09-28T03:31:00.238Z"
},
"statuses": {
"met": "the §15.0 required target is demonstrated by current evidence: a test that exercises it, and production evidence where the target is a production authority or state.",
@@@ -449,7 +449,7 @@
"metrics": [
{
"key": "deploy.drift",
-- "value": "25 service(s) not running origin/main"
++ "value": "24 service(s) not running origin/main"
}
]
},
ddiff --git a/docs/roadmap-baseline/requirement-ledger.md b/docs/roadmap-baseline/requirement-ledger.md
iindex 5d155398..de0450d4 100644
---- a/docs/roadmap-baseline/requirement-ledger.md
++++ b/docs/roadmap-baseline/requirement-ledger.md
@@@ -2,7 +2,7 @@
> Generated by `scripts/roadmap-baseline/generate.js`. Do not edit by hand; edit `data/*.json` or the extractor and regenerate.
--Roadmap §22.4 and §25: every D01-D46 requirement linked to the acceptance artifact that proves it. As of 2026-09-23T20:30Z; repositories scanned at origin/main (README), production snapshot 2026-09-28 03:25 UTC.
++Roadmap §22.4 and §25: every D01-D46 requirement linked to the acceptance artifact that proves it. As of 2026-09-23T20:30Z; repositories scanned at origin/main (README), production snapshot 2026-09-28 03:31 UTC.
This is the umbrella layer. §25.2 also asks for an atomic, source-level ledger (`docs/implementation/requirements-ledger.yaml`, one entry per field, route family, event, capability, journey and failure state); that ledger does not exist yet, and no row here may be read as closing the requirements beneath it.
@@@ -1155,7 +1155,7 @@ Remaining:
### D45 Release compatibility and recovery: partial
--Roadmap §3.2 (W0, 2026-09-22): absent. Waves: Track R, W22. Measured this run: 25 service(s) not running origin/main.
++Roadmap §3.2 (W0, 2026-09-22): absent. Waves: Track R, W22. Measured this run: 24 service(s) not running origin/main.
#### D45
ddiff --git a/scripts/roadmap-baseline/collect-prod.sh b/scripts/roadmap-baseline/collect-prod.sh
iindex 2023badf..387bab5b 100755
---- a/scripts/roadmap-baseline/collect-prod.sh
++++ b/scripts/roadmap-baseline/collect-prod.sh
@@@ -4,7 +4,8 @@
# scripts/roadmap-baseline/collect-prod.sh [ssh-host] (default: openvibe-ovh)
#
# Writes docs/roadmap-baseline/data/prod-snapshot.json. What it records, and nothing more:
--# - deployed git SHA per /opt/openvibe.<svc>, and the current release of /opt/openre.stream
++# - deployed git SHA per /opt/openvibe.<svc> (its current release when it uses the release layout), and the
++# current release of /opt/openre.stream
# - openvibe-* and openre-* systemd units and timers, with their state
# - every SQLite file under /opt/openvibe.*, /opt/openre.stream, /var/lib/openvibe-* and /var/lib/openre:
# size, owner and TABLE NAMES (sqlite3 -readonly, run as the file's owner; no rows read). The drill
@@@ -29,10 +30,15 @@ const git = (dir, ...args) => run('git', ['-c', `safe.directory=${dir}`, '-C', d
const deployments = {};
for (const d of fs.readdirSync('/opt').filter(n => n.startsWith('openvibe.')).sort()) {
const dir = '/opt/' + d;
++ // The release layout (ovhost, Live since 2026-09-27): current -> releases/<time>-<sha>, a git worktree of repo/.
++ // The top-level checkout is then the pre-release one and no longer what runs.
++ const rel = fs.existsSync(dir + '/current') ? sh(`readlink -f '${dir}/current'`) : '';
++ const src = rel || dir;
deployments[d.slice('openvibe.'.length)] = {
path: dir,
-- sha: git(dir, 'rev-parse', 'HEAD') || null,
-- committedAt: git(dir, 'log', '-1', '--format=%cI') || null,
++ ...(rel ? { layout: 'release', release: path.basename(rel) } : {}),
++ sha: git(src, 'rev-parse', 'HEAD') || null,
++ committedAt: git(src, 'log', '-1', '--format=%cI') || null,
};
}
// OpenRe.Stream uses the release layout: /opt/openre.stream/current -> releases/<sha prefix>, repo/ is the clone.
ddiff --git a/scripts/roadmap-baseline/generate.js b/scripts/roadmap-baseline/generate.js
iindex ec978a7c..1fddfc4a 100644
---- a/scripts/roadmap-baseline/generate.js
++++ b/scripts/roadmap-baseline/generate.js
@@@ -313,6 +313,8 @@ sortBy(envRows, 'repo', 'name');
const discrepancies = [];
const addD = (severity, area, subject, detail) => discrepancies.push({ severity, area, subject, detail });
// A unit spec ending in "@.service" is a template: it matches every instance (openre-rtmp-ingest@<release>.service).
++// Files that document or test a service and are not part of what it runs.
++const DOCS_OR_TESTS = /^(README\.md|STATUS\.json|CHANGELOG\.md|SECURITY\.md|docs\/.*\.md|docs\/roadmap-baseline\/|tests?\/|\.github\/)|\.test\.[cm]?[jt]s$/;
const unitMatches = (spec, unit) => spec.endsWith('@.service') ? unit.startsWith(spec.slice(0, -'.service'.length)) && unit.endsWith('.service') : spec === unit;
if (!prod) addD('unknown', 'production', 'all', 'prod-snapshot.json missing: run collect-prod.sh');
else {
@@@ -329,9 +331,13 @@ else {
} else if (dep.sha && target && dep.sha !== target) {
const behind = git(path.join(ROOT, s.repo), 'rev-list', '--count', `${dep.sha}..${target}`);
const ahead = git(path.join(ROOT, s.repo), 'rev-list', '--count', `${target}..${dep.sha}`);
-- addD('medium', 'deploy', s.id, behind === null
++ // Commits that change only documentation and tests (a README/STATUS refresh, re-recorded fixtures) need
++ // no deploy of their own; they ride the next one, so they rank below drift in what runs.
++ const changed = behind === null ? null : (git(path.join(ROOT, s.repo), 'diff', '--name-only', dep.sha, target) || '').split('\n').filter(Boolean);
++ const docsOnly = changed && changed.length && changed.every(f => DOCS_OR_TESTS.test(f));
++ addD(docsOnly ? 'low' : 'medium', 'deploy', s.id, behind === null
? `deployed ${dep.sha.slice(0, 7)} is not in the local clone (unknown commit)`
-- : `deployed ${dep.sha.slice(0, 7)} is ${behind} commit(s) behind origin/main ${target.slice(0, 7)}${ahead && ahead !== '0' ? `, ${ahead} ahead` : ''}`);
++ : `deployed ${dep.sha.slice(0, 7)} is ${behind} commit(s) behind origin/main ${target.slice(0, 7)}${ahead && ahead !== '0' ? `, ${ahead} ahead` : ''}${docsOnly ? `; only documentation and tests changed (${changed.length > 3 ? `${changed.slice(0, 3).join(', ')} and ${changed.length - 3} more` : changed.join(', ')})` : ''}`);
}
if (r && r.git.originMain && r.git.head && r.git.head !== r.git.originMain) {
addD('info', 'checkout', s.repo, `local checkout ${r.git.head.slice(0, 7)} differs from origin/main ${r.git.originMain.slice(0, 7)}; scan reflects the checkout`);