openvibers/openvibe.exchange Commits

AI text may describe people; only sex acts and porn stay gated (#22)

OP OpenVibers committed 11 days ago · 5b97572a7e · 7 files, +27 −75

* AI text may describe people; only sex acts and porn stay gated

* openvibe-sdk v0.81.0 (was v0.74.0)

Opened by scripts/pin-bump.js in OpenVibers/OpenVibe.Shared after the v0.81.0 release.

* Merge remote-tracking branch 'origin/main' into refresh-22

# Conflicts:
#	README.md
#	STATUS.json
#	package-lock.json
#	package.json

* Merge remote-tracking branch 'origin/pin-bump/openvibe-sdk-v0.81.0' into refresh-22

Changes

ddiff --git a/README.md b/README.md
iindex fd91dd3..d31438c 100644
---- a/README.md
++++ b/README.md
@@@ -80,7 +80,7 @@ Environment variable names are in [.env.example](.env.example); no value is comm
- **PostgreSQL** — `DATABASE_URL` (through PgBouncer) and `DATABASE_DIRECT_URL` (migrations); embedded PGlite in
`EXCHANGE_PGLITE_DIR` for development.
- **Valkey** — optional `VALKEY_URL`, `VALKEY_PREFIX` (readiness lists it; the limits in v1 count in-process).
--- **Packages** — `openvibe-contracts` v0.229.0, `openvibe-sdk` v0.74.0, `openvibe-shared` v4.93.2, the same tags
++- **Packages** — `openvibe-contracts` v0.229.0, `openvibe-sdk` v0.81.0, `openvibe-shared` v4.93.2, the same tags
OpenVibe.Meme pins.
## API
@@@ -207,6 +207,6 @@ AGPL-3.0-only. See [LICENSE](LICENSE).
<!-- versions:start -->
- openvibe-contracts: v0.235.0
--- openvibe-sdk: v0.74.0
++- openvibe-sdk: v0.81.0
- openvibe-shared: v4.93.2
<!-- versions:end -->
ddiff --git a/STATUS.json b/STATUS.json
iindex 7af281b..ae33f51 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -9,11 +9,11 @@
"port": "5150",
"domain": "openvibe.exchange",
"contracts": "openvibe-contracts v0.235.0",
-- "sdk": "openvibe-sdk v0.74.0",
++ "sdk": "openvibe-sdk v0.81.0",
"shared": "openvibe-shared v4.93.2",
"packages": [
"openvibe-contracts v0.235.0",
-- "openvibe-sdk v0.74.0",
++ "openvibe-sdk v0.81.0",
"openvibe-shared v4.93.2"
],
"summary": "OpenVibe.Exchange is the OpenVibe marketplace for what people make: agents, MCP tools, templates, design themes and kits, game assets and creator services. v1 is free and swap only — there is no price, no Billing and no money — and every listing carries a permission passport (reads, writes, spends, contacts) taken from its public manifest. Submitting a listing runs four conformance tests for its version and a draft is only publishable when they pass. A sandbox trial is a manifest/passport dry run (v1 does not execute a listing's code); a passed trial is consumed by the install, which keeps the exact passport snapshot. A revoke is one tap and idempotent. A free listing takes claims and a swap listing takes offers with what the other person gives; accepting closes it as given or swapped. Every public listing is one Search Fabric document queued in the service's outbox, with a tombstone on close or hide.",
ddiff --git a/package-lock.json b/package-lock.json
iindex 14157ec..8a70746 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -16,7 +16,7 @@
"helmet": "^8.1.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.235.0",
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.74.0",
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.81.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.93.2",
"pg": "^8.23.0"
},
@@@ -1166,9 +1166,9 @@
}
},
"node_modules/openvibe-sdk": {
-- "version": "0.74.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.74.0",
-- "integrity": "sha512-DO9KVPnUriY/I4lX6ZEJtXaUvRDbJyqnqJxvlpl+zkNGFILpmuBXVJogNOCfK071Qci1gg7C4Iw1Xrseklcajg==",
++ "version": "0.81.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.81.0",
++ "integrity": "sha512-GWD+qkkKiOyer1SATAaVs8qdWR1Z4WIRvtcYQU0NijzoL9BDRmkaXzLHjwwkRezdkHmdOgtvNIU8GAFaUaS8Ow==",
"license": "MIT",
"bin": {
"openvibe-download": "bin/openvibe-download.js"
ddiff --git a/package.json b/package.json
iindex 23829a2..6b89fc3 100644
---- a/package.json
++++ b/package.json
@@@ -25,7 +25,7 @@
"helmet": "^8.1.0",
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.235.0",
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.74.0",
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.81.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.93.2",
"pg": "^8.23.0"
},
ddiff --git a/server/text/no-looks.js b/server/text/no-looks.js
ddeleted file mode 100644
iindex 0b49d6b..0000000
---- a/server/text/no-looks.js
++++ /dev/null
@@@ -1,22 +0,0 @@
--'use strict';
--
--/**
-- * No looks in public AI text (the network rule, openvibe-sdk/no-looks, shared with Live, Community, MediaHub and
-- * Meme): an AI-written summary never describes a person's body, clothing, hair, face or guessed gender. Exchange
-- * v1 has no AI-written copy — a listing's words are the maker's own — but noLooks is here for the day an AI
-- * summary, sandbox description or catalogue line is generated. A summary that names looks is replaced by the
-- * listing's title, exactly as Live and Meme do; a maker's own verbatim text is never rewritten by this module.
-- */
--const { noLooks, hasLooks } = require('openvibe-sdk/no-looks');
--
--/** The summary to store for an AI-written listing summary. */
--function cleanSummary(title, summary) {
-- const t = String(title || '').trim() || 'Untitled listing';
-- const s = String(summary == null ? '' : summary).trim();
-- if (!s) return t;
-- if (hasLooks(s)) return t;
-- const cleaned = String(noLooks(s) || '').trim();
-- return cleaned || t;
--}
--
--module.exports = { cleanSummary, noLooks, hasLooks };
ddiff --git a/test/no-looks-guard.test.js b/test/no-looks-guard.test.js
nnew file mode 100644
iindex 0000000..5587d93
---- /dev/null
++++ b/test/no-looks-guard.test.js
@@@ -0,0 +1,18 @@
++'use strict';
++// Owner, 2026-10-31: AI may describe people; only sex acts and porn stay gated. No server file may call the old
++// looks filter again.
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++
++const root = path.join(__dirname, '..');
++const offenders = [];
++(function walk(dir) {
++ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
++ const p = path.join(dir, e.name);
++ if (e.isDirectory()) walk(p);
++ else if (e.name.endsWith('.js') && /\b(noLooks|noLooksTags|hasLooks)\s*\(|openvibe-sdk\/no-looks/.test(fs.readFileSync(p, 'utf8'))) offenders.push(path.relative(root, p));
++ }
++})(path.join(root, 'server'));
++assert.deepStrictEqual(offenders, [], 'no looks filter in server/');
++console.log('No looks filter: AI text describes people as written.');
ddiff --git a/test/no-looks.test.js b/test/no-looks.test.js
ddeleted file mode 100644
iindex 7677a90..0000000
---- a/test/no-looks.test.js
++++ /dev/null
@@@ -1,44 +0,0 @@
--'use strict';
--/**
-- * No looks in public AI text: a summary that names looks is replaced by the listing's title; an ordinary summary
-- * survives. Exchange v1 has no AI-written listing copy — this is the helper used the day a generated summary or
-- * sandbox line arrives, shared with Live, Community, MediaHub and Meme.
-- */
--const assert = require('assert');
--const { cleanSummary, hasLooks } = require('../server/text/no-looks');
--const { boot, check, done } = require('./helpers/boot');
--
--(async () => {
-- await check('a summary that names looks becomes the title', async () => {
-- assert.strictEqual(cleanSummary('Starter site template', 'A shirtless man in a kitchen laughs.'), 'Starter site template');
-- assert.strictEqual(cleanSummary('Starter site template', 'A pretty girl shows the theme.'), 'Starter site template');
-- assert.ok(hasLooks('A shirtless man in a kitchen laughs.'));
-- });
--
-- await check('an ordinary summary survives', async () => {
-- const s = cleanSummary('Starter site template', 'A static starter site with one page and no tracking.');
-- assert.strictEqual(s, 'A static starter site with one page and no tracking.');
-- });
--
-- const t = await boot();
-- try {
-- await check('a creator\'s own listing words are not rewritten by noLooks', async () => {
-- const user = t.network.addUser('maker');
-- const r = await t.get('/api/v1/listings', {
-- as: user,
-- json: {
-- title: 'A portrait lighting theme', kind: 'theme', mode: 'free',
-- summary: 'A warm portrait theme; the maker describes the lighting, not a person.',
-- license: 'MIT', version: '1.0.0',
-- manifest: { name: 'Portrait lighting', entry: 'theme.json', runtime: 'css' },
-- passport: { reads: [], writes: [], spends: [], contacts: [] },
-- },
-- });
-- assert.strictEqual(r.status, 201, r.text);
-- assert.strictEqual(r.json().summary, 'A warm portrait theme; the maker describes the lighting, not a person.');
-- });
-- } finally {
-- await t.close();
-- }
-- done();
--})();