openvibers/openvibe.codes Commits

Every harness in the catalog has an agent and offers advertise runtime:<class>, so routing can select any of them capability-first (#17)

OP OpenVibers committed 5 Oct 2026 · a1097e762d · 5 files, +127 −22

* Every harness in the catalog has an agent and offers advertise runtime:<class>, so routing can select any of them capability-first

**server/data/harness-offers.json**
- `server/data/harness-offers.json:132` — `command-code` now has one agent `command-code-default` (provider `commandcode`, model `command-code`, in 128000/out 32000, concurrency 2, all token prices 0).
- `server/data/harness-offers.json:182` — `opencode` gets one agent `opencode-default` (provider `opencode-go`, priced 0 the same way).
- `server/data/harness-offers.json:232` — `aider` gets one agent `aider-default` (provider `aider`, priced 0 the same way).

**server/domain/harness-placement.js**
- `server/domain/harness-placement.js:39` — `toOffer()` now also emits each declared runtime class as `runtime:<class>` (`...(caps.runtimes || []).map((r) => 'runtime:'+r)`), so `requirementsFor()` can require e.g. `runtime:code` capability-first.

**tests**
- `test/harness-placement.test.js:42,54,75` — added `runtime:code` to the expected capability lists.
- `test/harness-placement.test.js:67` — seed-offer count 3 → 6 (three new agents).
- `test/harness-placement.test.js:95` — candidate list now the six offers incl. command-code/opencode/aider.
- `test/harnesses-api.test.js:26` — replaced the stale “rows without an agent yet / agents: []” comment+assertion with one asserting every row returns ≥1 agent.

**Where my read differed from the brief**
- The brief’s “extend HARNESS_FLAGS” was already done by merged PR #16: `HARNESS_FLAGS` already carries all ten schema booleans (`host_access,mcp,long_autonomy,resume,edit,review,tools,vision,browser,computer_use`); only the `runtimes` → `runtime:<class>` emission was missing. No other flags exist in `platform/harness-offer.v1.json`.
- `test/harnesses.test.js:16` needed no change — still 6 rows.
- Named placement lines 113/135 needed no change (all offers stay external / nothing has `task:browse`); the failing assertions were actually 42/54/67/75/95.
- One unnamed test my change reaches does break: `test/layout.test.js:67` asserted the `/docs/harnesses` page contains “no agents yet”, which is now false. I updated it (`test/layout.test.js:66-71`) to assert each seed harness lists its agents’ models and the page no longer says “no agents yet”, and ran it as well.

**Tests** (`ov test test/harnesses.test.js test/harness-placement.test.js test/harnesses-api.test.js test/layout.test.js`): 4 passed in 7 s (3 named + `layout.test.js`). Not committed or pushed.

* Offers advertise task:edit/review only when the harness can, and deepseek no runtime (review)

Both findings are fixed and verified. Summary:

**Finding 1 — review routes could pick harnesses that cannot review** — Fixed in `server/domain/harness-placement.js:12-16,36`: `toOffer` now derives task kinds from the capability booleans (`caps.edit === true` → `task:edit`, `caps.review === true` → `task:review`) instead of the blanket `['edit','review']` default, with `row.task_capabilities` still overriding when set. Command Code and Aider now advertise only `task:edit`, and DeepSeek advertises neither, so a `review` route can no longer reach them. Test: `test/harness-placement.test.js:89` — covers the derived sets, the explicit-override path, review excluding the three, and edit excluding DeepSeek. Three existing expectations that assumed every catalog row could edit were updated to the new (intentional) reasons (`:141`, `:170`, `:184`).

**Finding 3 — DeepSeek advertised `runtime:code`** — Fixed in `server/data/harness-offers.json:266`: dropped `"runtimes": ["code"]` from the DeepSeek row, so its offer advertises no `runtime:*` capability. Test: `test/harness-placement.test.js:111` — asserts the offer's capabilities are `[]`, the row carries no `runtimes`, and a bare `runtime:code` requirement selects no DeepSeek offer while still selecting `claude-code`.

**Finding 2 — Contracts follow-up, not touched:** documenting `runtime:<class>` as a kind-harness capability name (alongside `worker:<class>` in `$defs.reservedWorkerCapabilities`) belongs in `openvibe-contracts`' `platform/resource-offer@1` capabilities description; I left Contracts alone as instructed. Noted for a separate Contracts change.

**Test results:** `ov test test/harness-placement.test.js test/harnesses.test.js test/harnesses-api.test.js test/layout.test.js` → **4 passed** (`harness-placement` 0.5s, `harnesses-api` 6.7s, `harnesses` 0.4s, `layout` 4.4s). Nothing committed or pushed.

Changes

ddiff --git a/server/data/harness-offers.json b/server/data/harness-offers.json
iindex 7f883b6..7e79efc 100644
---- a/server/data/harness-offers.json
++++ b/server/data/harness-offers.json
@@@ -129,7 +129,25 @@
"max_concurrent_runs": 2,
"max_context_tokens": 128000
},
-- "agents": []
++ "agents": [
++ {
++ "id": "command-code-default",
++ "harness": "command-code",
++ "provider": "commandcode",
++ "model": "command-code",
++ "context_limits": {
++ "input_tokens": 128000,
++ "output_tokens": 32000
++ },
++ "concurrency": 2,
++ "price_per_1k_tokens": {
++ "fresh_usd": 0,
++ "cached_usd": 0,
++ "output_usd": 0
++ },
++ "availability_windows": []
++ }
++ ]
},
{
"id": "opencode",
@@@ -161,7 +179,25 @@
"max_concurrent_runs": 2,
"max_context_tokens": 128000
},
-- "agents": []
++ "agents": [
++ {
++ "id": "opencode-default",
++ "harness": "opencode",
++ "provider": "opencode-go",
++ "model": "opencode",
++ "context_limits": {
++ "input_tokens": 128000,
++ "output_tokens": 32000
++ },
++ "concurrency": 2,
++ "price_per_1k_tokens": {
++ "fresh_usd": 0,
++ "cached_usd": 0,
++ "output_usd": 0
++ },
++ "availability_windows": []
++ }
++ ]
},
{
"id": "aider",
@@@ -193,7 +229,25 @@
"max_concurrent_runs": 2,
"max_context_tokens": 128000
},
-- "agents": []
++ "agents": [
++ {
++ "id": "aider-default",
++ "harness": "aider",
++ "provider": "aider",
++ "model": "aider",
++ "context_limits": {
++ "input_tokens": 128000,
++ "output_tokens": 32000
++ },
++ "concurrency": 2,
++ "price_per_1k_tokens": {
++ "fresh_usd": 0,
++ "cached_usd": 0,
++ "output_usd": 0
++ },
++ "availability_windows": []
++ }
++ ]
},
{
"id": "deepseek",
@@@ -209,8 +263,7 @@
"tools": false,
"vision": false,
"browser": false,
-- "computer_use": false,
-- "runtimes": ["code"]
++ "computer_use": false
},
"address": {
"kind": "api",
ddiff --git a/server/domain/harness-placement.js b/server/domain/harness-placement.js
iindex c39b2a7..645d515 100644
---- a/server/domain/harness-placement.js
++++ b/server/domain/harness-placement.js
@@@ -7,8 +7,14 @@
const contracts = require('openvibe-contracts');
const { plan } = require('openvibe-sdk/placement');
--// A catalog row without task_capabilities takes edit and review.
--const DEFAULT_TASKS = ['edit', 'review'];
++// A catalog row without task_capabilities derives its task kinds from the capability booleans:
++// edit needs capabilities.edit === true, review needs capabilities.review === true.
++const TASK_FLAGS = ['edit', 'review'];
++
++function tasksFor(caps) {
++ return TASK_FLAGS.filter((task) => caps[task] === true);
++}
++
// harness-offer@1 capability flag → the resource-offer@1 capability it adds when true.
const HARNESS_FLAGS = {
host_access: 'harness:host-access', mcp: 'harness:mcp', long_autonomy: 'harness:long-autonomy', resume: 'harness:resume',
@@@ -27,7 +33,7 @@ function toOffer(harness, agent, opts = {}) {
const { agents, ...row } = harness;
const caps = row.capabilities || {};
const limits = row.limits || {};
-- const tasks = row.task_capabilities || DEFAULT_TASKS;
++ const tasks = row.task_capabilities || tasksFor(caps);
const maxContextTokens = (agent.context_limits && agent.context_limits.input_tokens) ?? limits.max_context_tokens;
const health = typeof opts.health === 'string' ? { status: opts.health } : opts.health || { status: 'up' };
const offer = {
@@@ -36,7 +42,7 @@ function toOffer(harness, agent, opts = {}) {
provider: agent.provider || harness.provider,
region: 'global',
trust: opts.trust || 'external',
-- capabilities: [...tasks.map((task) => `task:${task}`), ...Object.keys(HARNESS_FLAGS).filter((name) => caps[name] === true).map((name) => HARNESS_FLAGS[name])],
++ capabilities: [...tasks.map((task) => `task:${task}`), ...Object.keys(HARNESS_FLAGS).filter((name) => caps[name] === true).map((name) => HARNESS_FLAGS[name]), ...(caps.runtimes || []).map((runtime) => `runtime:${runtime}`)],
capacity: { workers: { harness: limits.max_concurrent_runs } },
health,
pricing: { model: 'per-operation', unit: 'token', marginal_usd_per_unit: agent.price_per_1k_tokens.fresh_usd / 1000 },
ddiff --git a/test/harness-placement.test.js b/test/harness-placement.test.js
iindex 3a5c67c..e039f89 100644
---- a/test/harness-placement.test.js
++++ b/test/harness-placement.test.js
@@@ -5,6 +5,7 @@ const fs = require('fs');
const path = require('path');
const contracts = require('openvibe-contracts');
const { createHarnesses } = require('../server/domain/harnesses');
++const { plan } = require('openvibe-sdk/placement');
const { TASKS, toOffer, requirementsFor, route } = require('../server/domain/harness-placement');
const { check, done } = require('./helpers/boot');
@@@ -39,19 +40,19 @@ function priced(row, freshUsd) {
provider: 'example',
region: 'global',
trust: 'partner',
-- capabilities: ['task:edit', 'task:review', 'harness:host-access', 'harness:mcp', 'harness:resume', 'harness:edit', 'harness:tools'],
++ capabilities: ['task:edit', 'harness:host-access', 'harness:mcp', 'harness:resume', 'harness:edit', 'harness:tools', 'runtime:code'],
capacity: { workers: { harness: 2 } },
health: { status: 'degraded' },
pricing: { model: 'per-operation', unit: 'token', marginal_usd_per_unit: 0.003 / 1000 },
updated_at: '2026-10-02T12:00:00.000Z',
-- detail: { ...row, limits: { ...row.limits, max_context_tokens: 100000 }, task_capabilities: ['edit', 'review'] },
++ detail: { ...row, limits: { ...row.limits, max_context_tokens: 100000 }, task_capabilities: ['edit'] },
latency_ms: { run_p95: 900 },
});
const deepseek = rows.find((row) => row.id === 'deepseek');
const offer = toOffer(deepseek, deepseek.agents[0]);
assert.strictEqual(offer.offer_id, 'deepseek:deepseek-chat');
-- assert.deepStrictEqual(offer.capabilities, ['task:edit', 'task:review']);
++ assert.deepStrictEqual(offer.capabilities, []);
assert.strictEqual(offer.trust, 'external');
assert.deepStrictEqual(offer.health, { status: 'up' });
assert.strictEqual('latency_ms' in offer, false);
@@@ -64,7 +65,7 @@ function priced(row, freshUsd) {
await check('every seed offer validates as platform.resource-offer@1 of kind harness', async () => {
const harnesses = createHarnesses({ catalogPath });
const offers = harnesses.list().flatMap((harness) => harnesses.agents(harness.id).map((agent) => [harness, toOffer(harness, agent, { now })]));
-- assert.strictEqual(offers.length, 3);
++ assert.strictEqual(offers.length, 6);
for (const [harness, offer] of offers) {
const result = contracts.validate('platform.resource-offer@1', JSON.parse(JSON.stringify(offer)));
assert.ok(result.valid, `${offer.offer_id}: ${JSON.stringify(result.errors)}`);
@@@ -72,7 +73,7 @@ function priced(row, freshUsd) {
}
const browsing = { ...rows[0], task_capabilities: ['edit', 'browse'] };
const offer = toOffer(browsing, browsing.agents[0], { now });
-- assert.deepStrictEqual(offer.capabilities, ['task:edit', 'task:browse', 'harness:host-access', 'harness:mcp', 'harness:long-autonomy', 'harness:resume', 'harness:edit', 'harness:review', 'harness:tools', 'harness:vision']);
++ assert.deepStrictEqual(offer.capabilities, ['task:edit', 'task:browse', 'harness:host-access', 'harness:mcp', 'harness:long-autonomy', 'harness:resume', 'harness:edit', 'harness:review', 'harness:tools', 'harness:vision', 'runtime:code']);
assert.ok(contracts.validate('platform.resource-offer@1', JSON.parse(JSON.stringify(offer))).valid);
});
@@@ -85,6 +86,40 @@ function priced(row, freshUsd) {
assert.strictEqual(req.objective, 'balanced');
});
++ await check('task capabilities derive from the capability booleans', async () => {
++ const byId = new Map(rows.map((row) => [row.id, row]));
++ const tasksOf = (id) => toOffer(byId.get(id), byId.get(id).agents[0]).detail.task_capabilities;
++ assert.deepStrictEqual(tasksOf('claude-code'), ['edit', 'review']);
++ assert.deepStrictEqual(tasksOf('command-code'), ['edit']);
++ assert.deepStrictEqual(tasksOf('aider'), ['edit']);
++ assert.deepStrictEqual(tasksOf('deepseek'), []);
++ // An explicit task_capabilities list still overrides the booleans.
++ const claude = byId.get('claude-code');
++ assert.deepStrictEqual(toOffer({ ...claude, task_capabilities: ['edit', 'browse'] }, claude.agents[0]).detail.task_capabilities, ['edit', 'browse']);
++
++ const harnesses = createHarnesses({ catalogPath });
++ const review = route({ task: 'review', harnesses, now });
++ for (const id of ['command-code:command-code-default', 'aider:aider-default', 'deepseek:deepseek-chat']) {
++ assert.deepStrictEqual(review.candidates.find((c) => c.id === id), { id, included: false, reason: 'lacks task:review' });
++ }
++ assert.ok(!['command-code', 'aider', 'deepseek'].includes(review.selected.split(':')[0]));
++ const edit = route({ task: 'edit', harnesses, now });
++ assert.deepStrictEqual(edit.candidates.find((c) => c.id === 'deepseek:deepseek-chat'), { id: 'deepseek:deepseek-chat', included: false, reason: 'lacks task:edit' });
++ assert.ok(edit.candidates.some((c) => c.id === 'command-code:command-code-default' && c.included));
++ });
++
++ await check('deepseek advertises no runtime class', async () => {
++ const deepseek = rows.find((row) => row.id === 'deepseek');
++ const offer = toOffer(deepseek, deepseek.agents[0]);
++ assert.deepStrictEqual(offer.capabilities, []);
++ assert.strictEqual('runtimes' in offer.detail.capabilities, false);
++ // A bare runtime:code requirement no longer reaches the host-less API, but still reaches a code CLI.
++ const req = { kind: 'harness.edit', mobility: 'job', latency_class: 'interactive', objective: 'balanced', capabilities: ['runtime:code'] };
++ assert.strictEqual(plan(req, [offer], { now }).selected, null);
++ const claude = rows.find((row) => row.id === 'claude-code');
++ assert.strictEqual(plan(req, [toOffer(claude, claude.agents[0])], { now }).selected, 'claude-code:claude-code-sonnet');
++ });
++
await check('a review task selects a review-capable offer', async () => {
const harnesses = createHarnesses({ catalogPath });
const r = route({ task: 'review', harnesses, now });
@@@ -92,7 +127,7 @@ function priced(row, freshUsd) {
const [harnessId] = r.selected.split(':');
assert.ok(toOffer(harnesses.get(harnessId), harnesses.agents(harnessId)[0]).capabilities.includes('task:review'));
assert.ok(r.reasons.length);
-- assert.deepStrictEqual(r.candidates.map((c) => c.id), ['claude-code:claude-code-sonnet', 'codex:codex-default', 'deepseek:deepseek-chat']);
++ assert.deepStrictEqual(r.candidates.map((c) => c.id), ['claude-code:claude-code-sonnet', 'codex:codex-default', 'command-code:command-code-default', 'opencode:opencode-default', 'aider:aider-default', 'deepseek:deepseek-chat']);
});
await check('an offer whose health is down is excluded with a reason', async () => {
@@@ -106,9 +141,11 @@ function priced(row, freshUsd) {
const harnesses = createHarnesses({ catalogPath });
const r = route({ task: 'edit', extra: { trust: 'first-party' }, harnesses, now, opts: { 'codex:codex-default': { trust: 'first-party' } } });
assert.strictEqual(r.selected, 'codex:codex-default');
-- for (const c of r.candidates.filter((c) => c.id !== 'codex:codex-default')) {
++ for (const c of r.candidates.filter((c) => c.id !== 'codex:codex-default' && c.id !== 'deepseek:deepseek-chat')) {
assert.deepStrictEqual(c, { id: c.id, included: false, reason: 'workload requires first-party trust' });
}
++ // Deepseek cannot edit, so it drops out on capabilities before trust is considered.
++ assert.deepStrictEqual(r.candidates.find((c) => c.id === 'deepseek:deepseek-chat'), { id: 'deepseek:deepseek-chat', included: false, reason: 'lacks task:edit' });
const none = route({ task: 'edit', extra: { trust: ['first-party'] }, harnesses, now });
assert.strictEqual(none.selected, null);
assert.ok(none.candidates.every((c) => !c.included));
@@@ -133,7 +170,11 @@ function priced(row, freshUsd) {
assert.deepStrictEqual(r.candidates.find((c) => c.id === 'codex:codex-default'), { id: 'codex:codex-default', included: false, reason: 'lacks task:browse' });
const none = route({ task: 'edit', extra: { capabilities: ['task:browse'] }, harnesses: createHarnesses({ catalogPath }), now });
assert.strictEqual(none.selected, null);
-- assert.ok(none.candidates.every((c) => c.reason === 'lacks task:browse'));
++ for (const c of none.candidates.filter((c) => c.id !== 'deepseek:deepseek-chat')) {
++ assert.strictEqual(c.reason, 'lacks task:browse');
++ }
++ // Deepseek drops on capabilities it lacks (edit) before task:browse.
++ assert.deepStrictEqual(none.candidates.find((c) => c.id === 'deepseek:deepseek-chat'), { id: 'deepseek:deepseek-chat', included: false, reason: 'lacks task:edit' });
});
await check('a harness:vision requirement drops the vision:false harnesses', async () => {
@@@ -143,7 +184,7 @@ function priced(row, freshUsd) {
for (const id of ['claude-code:claude-code-sonnet', 'codex:codex-default']) {
assert.deepStrictEqual(r.candidates.find((c) => c.id === id), { id, included: true, reason: null });
}
-- assert.deepStrictEqual(r.candidates.find((c) => c.id === 'deepseek:deepseek-chat'), { id: 'deepseek:deepseek-chat', included: false, reason: 'lacks harness:vision' });
++ assert.deepStrictEqual(r.candidates.find((c) => c.id === 'command-code:command-code-default'), { id: 'command-code:command-code-default', included: false, reason: 'lacks harness:vision' });
assert.ok(toOffer(harnesses.get(r.selected.split(':')[0]), harnesses.agents(r.selected.split(':')[0])[0]).capabilities.includes('harness:vision'));
});
ddiff --git a/test/harnesses-api.test.js b/test/harnesses-api.test.js
iindex c767dd0..5b4e478 100644
---- a/test/harnesses-api.test.js
++++ b/test/harnesses-api.test.js
@@@ -23,8 +23,9 @@ const rows = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'server', 'da
assert.ok(harnesses.some((h) => h.id === 'opencode'), "GET /harnesses includes the 'opencode' harness");
for (const row of rows) {
const h = harnesses.find((x) => x.id === row.id);
-- // Seed rows without an agent yet (command-code, aider, opencode) come back with agents: [].
-- assert.deepStrictEqual(h, { ...row, agents: row.agents || [] });
++ // Every seed row ships at least one agent (command-code, aider and opencode each carry one subscription pool).
++ assert.deepStrictEqual(h, { ...row, agents: row.agents });
++ assert.ok(h.agents.length > 0, `${row.id} has an agent`);
}
});
ddiff --git a/test/layout.test.js b/test/layout.test.js
iindex 5a34ebc..f7362b3 100644
---- a/test/layout.test.js
++++ b/test/layout.test.js
@@@ -63,8 +63,12 @@ const BOOST = /<script src="\/shared\/boost\.js\?v=[0-9a-f]{12}" data-main="#mai
assert.strictEqual(r.status, 200, r.text.slice(0, 300));
assert.match(r.headers.get('content-type'), /^text\/html/);
const rows = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'server', 'data', 'harness-offers.json'), 'utf8'));
-- for (const h of rows) assert.ok(r.text.includes(`<code>${h.id}</code>`), `${h.id} listed`);
-- assert.ok(r.text.includes('no agents yet'), 'a harness without agents says "no agents yet"');
++ for (const h of rows) {
++ assert.ok(r.text.includes(`<code>${h.id}</code>`), `${h.id} listed`);
++ assert.ok(h.agents.length > 0, `${h.id} has an agent`);
++ for (const a of h.agents) assert.ok(r.text.includes(a.model), `${h.id} lists ${a.model}`);
++ }
++ assert.ok(!r.text.includes('no agents yet'), 'every seed harness has an agent');
assert.ok(!r.text.includes('/home/') && !r.text.includes('/mnt/'), 'no local filesystem path on the page');
});