jev-layer 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -34
- package/CONTRIBUTING.md +146 -146
- package/LICENSE +21 -21
- package/README.md +123 -126
- package/README.ru.md +138 -117
- package/README.zh-CN.md +137 -117
- package/RELEASE.md +53 -53
- package/SECURITY.md +56 -56
- package/bin/jev.mjs +213 -213
- package/config/codex.mcp.toml +8 -8
- package/config/generic-mcp.json +13 -13
- package/config/hermes.mcp.yaml +9 -9
- package/config/jev.example.json +22 -22
- package/config/omp.mcp.json +14 -14
- package/config/providers.env.example +13 -13
- package/docs/AGENT-IMPLEMENTATION.md +250 -0
- package/docs/COMPATIBILITY.md +15 -15
- package/docs/HERMES-LOCAL-AGENT-HANDOFF.ru.md +177 -0
- package/docs/PROVIDERS.md +67 -0
- package/docs/SCHEMA-VERSIONING.md +96 -94
- package/docs/architecture.svg +77 -0
- package/docs/jev-layer-banner.svg +38 -0
- package/examples/capabilities.json +39 -39
- package/examples/route-request.json +28 -28
- package/integrations/codex/.codex-plugin/plugin.json +19 -19
- package/integrations/codex/.mcp.json +11 -11
- package/integrations/codex/AGENTS.md +1 -1
- package/integrations/codex/run-mcp.mjs +9 -9
- package/integrations/codex/skills/jev-route/SKILL.md +17 -17
- package/integrations/hermes/__init__.py +150 -51
- package/integrations/hermes/plugin.yaml +10 -5
- package/integrations/hermes/schemas.py +89 -12
- package/integrations/omp/extension.js +105 -105
- package/integrations/template/README.md +10 -10
- package/integrations/template/adapter.mjs +87 -87
- package/package.json +60 -59
- package/scripts/benchmark.mjs +35 -35
- package/scripts/browser-benchmark.mjs +92 -92
- package/scripts/browser-e2e.mjs +117 -117
- package/scripts/capability-e2e.mjs +31 -31
- package/scripts/clean-install-smoke.mjs +162 -162
- package/scripts/codex-mcp-smoke.mjs +119 -119
- package/scripts/context-filter-e2e.mjs +45 -45
- package/scripts/fail-open-smoke.mjs +120 -120
- package/scripts/feature-flags-smoke.mjs +46 -46
- package/scripts/mcp-receipt-smoke.mjs +113 -98
- package/scripts/model-route-report.mjs +15 -0
- package/scripts/openrouter-choice.mjs +59 -59
- package/scripts/replay-eval.mjs +124 -124
- package/scripts/smoke.mjs +34 -34
- package/scripts/supervision-e2e.mjs +138 -109
- package/src/browser.mjs +571 -569
- package/src/cli.mjs +33 -33
- package/src/config.mjs +85 -75
- package/src/context-filter.mjs +56 -56
- package/src/contract.mjs +72 -72
- package/src/discovery.mjs +65 -65
- package/src/hermes-adapter.mjs +123 -0
- package/src/mcp-server.mjs +267 -210
- package/src/model-route-metrics.mjs +89 -0
- package/src/model-routing.mjs +87 -0
- package/src/providers/demo.mjs +52 -52
- package/src/providers/index.mjs +12 -0
- package/src/providers/typesafe.mjs +126 -126
- package/src/receipts.mjs +227 -226
- package/src/registry.mjs +109 -109
- package/src/relevance-filter.mjs +99 -99
- package/src/route.mjs +219 -221
- package/src/shadow-compaction.mjs +170 -0
- package/src/supervision.mjs +268 -244
- package/test/browser.test.mjs +199 -199
- package/test/capability.test.mjs +54 -54
- package/test/context-filter.test.mjs +65 -65
- package/test/hermes-adapter.test.mjs +62 -0
- package/test/model-route-metrics.test.mjs +61 -0
- package/test/model-routing.test.mjs +59 -0
- package/test/openrouter-provider.test.mjs +55 -55
- package/test/provider-transports.test.mjs +205 -0
- package/test/providers.test.mjs +126 -0
- package/test/receipts.test.mjs +71 -71
- package/test/route.test.mjs +74 -74
- package/test/shadow-compaction.test.mjs +67 -0
- package/test/supervision.test.mjs +117 -99
|
@@ -1,94 +1,96 @@
|
|
|
1
|
-
# Schema and compatibility policy
|
|
2
|
-
|
|
3
|
-
[English](../README.md) | [Русский](../README.ru.md) | [简体中文](../README.zh-CN.md)
|
|
4
|
-
|
|
5
|
-
The current public contracts are **schema version 1**. The implementation already emits `schema_version: 1` for route requests, decision envelopes, routing cases, execution receipts, and supervision cases. A new public release must not silently change the meaning of those v1 fields.
|
|
6
|
-
|
|
7
|
-
## Version rules
|
|
8
|
-
|
|
9
|
-
- **Patch release:** bug fixes and documentation changes; v1 meanings remain unchanged.
|
|
10
|
-
- **Minor release:** additive optional fields, new providers, new adapters, or new capability kinds that v1 consumers can ignore.
|
|
11
|
-
- **Major release:** removed/renamed required fields, changed field types or meanings, changed correlation semantics, or a host-approval contract change.
|
|
12
|
-
- Unknown fields must be ignored by readers. Writers must not emit a required field unless it is part of the declared schema version.
|
|
13
|
-
- New runtime behavior must remain opt-in and fail open unless the existing contract explicitly requires it.
|
|
14
|
-
|
|
15
|
-
A breaking schema requires a new schema version, migration notes, fixtures for both versions, and an adapter compatibility decision. Do not change v1 to avoid writing a migration.
|
|
16
|
-
|
|
17
|
-
## MCP tools
|
|
18
|
-
|
|
19
|
-
The MCP server currently exposes these stable tool names:
|
|
20
|
-
|
|
21
|
-
- `jev_route`
|
|
22
|
-
- `jev_browser_step` (experimental, opt-in)
|
|
23
|
-
- `jev_supervise` (experimental, opt-in)
|
|
24
|
-
- `
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- `
|
|
35
|
-
- `
|
|
36
|
-
- `
|
|
37
|
-
- `
|
|
38
|
-
- `
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
- `
|
|
42
|
-
- `
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- `
|
|
53
|
-
- `
|
|
54
|
-
- `
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- `record_type: "
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
1
|
+
# Schema and compatibility policy
|
|
2
|
+
|
|
3
|
+
[English](../README.md) | [Русский](../README.ru.md) | [简体中文](../README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
The current public contracts are **schema version 1**. The implementation already emits `schema_version: 1` for route requests, decision envelopes, routing cases, execution receipts, and supervision cases. A new public release must not silently change the meaning of those v1 fields.
|
|
6
|
+
|
|
7
|
+
## Version rules
|
|
8
|
+
|
|
9
|
+
- **Patch release:** bug fixes and documentation changes; v1 meanings remain unchanged.
|
|
10
|
+
- **Minor release:** additive optional fields, new providers, new adapters, or new capability kinds that v1 consumers can ignore.
|
|
11
|
+
- **Major release:** removed/renamed required fields, changed field types or meanings, changed correlation semantics, or a host-approval contract change.
|
|
12
|
+
- Unknown fields must be ignored by readers. Writers must not emit a required field unless it is part of the declared schema version.
|
|
13
|
+
- New runtime behavior must remain opt-in and fail open unless the existing contract explicitly requires it.
|
|
14
|
+
|
|
15
|
+
A breaking schema requires a new schema version, migration notes, fixtures for both versions, and an adapter compatibility decision. Do not change v1 to avoid writing a migration.
|
|
16
|
+
|
|
17
|
+
## MCP tools
|
|
18
|
+
|
|
19
|
+
The MCP server currently exposes these stable tool names:
|
|
20
|
+
|
|
21
|
+
- `jev_route`
|
|
22
|
+
- `jev_browser_step` (experimental, opt-in)
|
|
23
|
+
- `jev_supervise` (experimental, opt-in)
|
|
24
|
+
- `jev_model_route` (report-only; experimental, opt-in)
|
|
25
|
+
- `jev_shadow_compaction` (report-only; experimental, opt-in)
|
|
26
|
+
- `jev_record_execution`
|
|
27
|
+
|
|
28
|
+
Their input and structured output are v1. Additive optional properties are compatible. Renaming a tool, changing a required property, changing the meaning of a status, or changing who owns execution requires a new tool/schema version and adapter migration. Keep `tools/list`, `initialize`, and stdio JSON-RPC behavior backward compatible for v1 clients.
|
|
29
|
+
|
|
30
|
+
## Routing decision schema
|
|
31
|
+
|
|
32
|
+
A v1 decision includes at least:
|
|
33
|
+
|
|
34
|
+
- `schema_version`
|
|
35
|
+
- `correlation_id`
|
|
36
|
+
- `status`
|
|
37
|
+
- `selected`
|
|
38
|
+
- `confidence`
|
|
39
|
+
- `probabilities`
|
|
40
|
+
- `reason`
|
|
41
|
+
- `candidates`
|
|
42
|
+
- `fallback`
|
|
43
|
+
- `execution` with host execution initially `not_started`
|
|
44
|
+
- `receipt`
|
|
45
|
+
|
|
46
|
+
The selected id is advisory until the host resolves it against its own capability registry and permissions. `correlation_id` is the join key for routing and execution records.
|
|
47
|
+
|
|
48
|
+
## Execution receipts
|
|
49
|
+
|
|
50
|
+
A v1 `execution_receipt` is append-only JSONL data with:
|
|
51
|
+
|
|
52
|
+
- `record_type: "execution_receipt"`
|
|
53
|
+
- `schema_version: 1`
|
|
54
|
+
- `receipt_id`
|
|
55
|
+
- `correlation_id`
|
|
56
|
+
- `harness`
|
|
57
|
+
- the selected/candidate decision summary;
|
|
58
|
+
- Jev provider, latency, cost, and status;
|
|
59
|
+
- bounded host status/result/error plus optional exit and timing metadata.
|
|
60
|
+
|
|
61
|
+
The host must record `completed`, `failed`, or `not_started`. Receipts must not contain unbounded prompts, secrets, or raw credentials. Receipts are evidence of what the host reported; they do not grant permission or prove that Jev executed anything.
|
|
62
|
+
|
|
63
|
+
## Replay cases
|
|
64
|
+
|
|
65
|
+
A v1 replay file is JSONL. Supported records include:
|
|
66
|
+
|
|
67
|
+
- `record_type: "routing_case"`
|
|
68
|
+
- `record_type: "execution_receipt"`
|
|
69
|
+
- `record_type: "supervision_case"`
|
|
70
|
+
|
|
71
|
+
Routing cases retain a sanitized request and a decision summary. `supervision_case.supervision.evidence_state` is an optional v1 object with `state` (`present`, `missing`, or `contradictory`) and bounded source labels. Replay reads cases without calling host tools. New optional record fields are compatible; changing record type, correlation semantics, or the meaning of a recorded status requires a new replay schema and migration.
|
|
72
|
+
|
|
73
|
+
## Adapter contract
|
|
74
|
+
|
|
75
|
+
The adapter contract is currently **v1** and is intentionally separate from provider/model versions. A v1 adapter must:
|
|
76
|
+
|
|
77
|
+
1. submit a bounded candidate set;
|
|
78
|
+
2. call `jev_route` or the equivalent CLI contract;
|
|
79
|
+
3. preserve `correlation_id`;
|
|
80
|
+
4. keep native execution and permissions in the host;
|
|
81
|
+
5. preserve approval decisions;
|
|
82
|
+
6. call `jev_record_execution` after host execution or denial;
|
|
83
|
+
7. fail open to the native path when Jev is unavailable or inconclusive.
|
|
84
|
+
|
|
85
|
+
An adapter that cannot preserve these invariants is not v1-compatible. Record supported adapter versions in integration documentation and release checklists.
|
|
86
|
+
|
|
87
|
+
## Compatibility review
|
|
88
|
+
|
|
89
|
+
For every release, review:
|
|
90
|
+
|
|
91
|
+
- v1 request/decision fixtures;
|
|
92
|
+
- MCP `tools/list` and `tools/call` smoke cases;
|
|
93
|
+
- receipt/replay round trips;
|
|
94
|
+
- all supported adapter examples;
|
|
95
|
+
- fail-open and approval-denial paths;
|
|
96
|
+
- package contents and translated documentation.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">jev-layer architecture</title>
|
|
3
|
+
<desc id="desc">Agent harnesses submit bounded requests to jev-layer. The host owns permissions and execution, while jev-layer returns a decision and records receipts for replay.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="surface" x1="0" y1="0" x2="1" y2="1">
|
|
6
|
+
<stop offset="0" stop-color="#f8fbff"/>
|
|
7
|
+
<stop offset="1" stop-color="#e9f3f8"/>
|
|
8
|
+
</linearGradient>
|
|
9
|
+
<linearGradient id="decision" x1="0" y1="0" x2="1" y2="1">
|
|
10
|
+
<stop offset="0" stop-color="#12314c"/>
|
|
11
|
+
<stop offset="1" stop-color="#14525a"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
<linearGradient id="evidence" x1="0" y1="0" x2="1" y2="1">
|
|
14
|
+
<stop offset="0" stop-color="#eefcf7"/>
|
|
15
|
+
<stop offset="1" stop-color="#d8f3ee"/>
|
|
16
|
+
</linearGradient>
|
|
17
|
+
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
|
|
18
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#228e9b"/>
|
|
19
|
+
</marker>
|
|
20
|
+
<marker id="arrowLight" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
|
|
21
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#b6e9e0"/>
|
|
22
|
+
</marker>
|
|
23
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
24
|
+
<feDropShadow dx="0" dy="8" stdDeviation="10" flood-color="#183b52" flood-opacity="0.13"/>
|
|
25
|
+
</filter>
|
|
26
|
+
</defs>
|
|
27
|
+
<rect width="1280" height="720" rx="28" fill="url(#surface)"/>
|
|
28
|
+
<text x="640" y="56" text-anchor="middle" fill="#102c45" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="28" font-weight="750">Host-owned execution, bounded decisions</text>
|
|
29
|
+
<text x="640" y="86" text-anchor="middle" fill="#567086" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="16">jev-layer chooses and records; the host validates and acts</text>
|
|
30
|
+
|
|
31
|
+
<g filter="url(#shadow)">
|
|
32
|
+
<rect x="70" y="145" width="300" height="205" rx="22" fill="#ffffff" stroke="#9bb4c7" stroke-width="2"/>
|
|
33
|
+
<rect x="70" y="145" width="300" height="52" rx="22" fill="#e6f0f6"/>
|
|
34
|
+
<path d="M70 175h300" stroke="#e6f0f6" stroke-width="2"/>
|
|
35
|
+
<text x="220" y="179" text-anchor="middle" fill="#173c57" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="20" font-weight="750">Agent harnesses</text>
|
|
36
|
+
<text x="104" y="232" fill="#294c63" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">Hermes · OMP · Codex</text>
|
|
37
|
+
<text x="104" y="264" fill="#294c63" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">generic MCP clients</text>
|
|
38
|
+
<text x="104" y="309" fill="#637d90" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="15">supplies intent, candidates, context</text>
|
|
39
|
+
</g>
|
|
40
|
+
|
|
41
|
+
<g filter="url(#shadow)">
|
|
42
|
+
<rect x="490" y="120" width="300" height="255" rx="22" fill="url(#decision)" stroke="#66e3c4" stroke-width="3"/>
|
|
43
|
+
<text x="640" y="168" text-anchor="middle" fill="#ffffff" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="26" font-weight="750">jev-layer</text>
|
|
44
|
+
<text x="640" y="195" text-anchor="middle" fill="#a9e8db" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="15" font-weight="650">SYSTEM-1 DECISION LAYER</text>
|
|
45
|
+
<path d="M535 222h210M535 273h210M535 324h210" stroke="#6ea7ac" stroke-opacity="0.55"/>
|
|
46
|
+
<text x="640" y="247" text-anchor="middle" fill="#f2ffff" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">route · supervise</text>
|
|
47
|
+
<text x="640" y="298" text-anchor="middle" fill="#f2ffff" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">context filter · fail-open</text>
|
|
48
|
+
<text x="640" y="349" text-anchor="middle" fill="#b6e9e0" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="15">returns one bounded decision + id</text>
|
|
49
|
+
</g>
|
|
50
|
+
|
|
51
|
+
<g filter="url(#shadow)">
|
|
52
|
+
<rect x="910" y="145" width="300" height="205" rx="22" fill="#ffffff" stroke="#9bb4c7" stroke-width="2"/>
|
|
53
|
+
<rect x="910" y="145" width="300" height="52" rx="22" fill="#e6f0f6"/>
|
|
54
|
+
<text x="1060" y="179" text-anchor="middle" fill="#173c57" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="20" font-weight="750">Host policy boundary</text>
|
|
55
|
+
<text x="944" y="232" fill="#294c63" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">permissions · approvals</text>
|
|
56
|
+
<text x="944" y="264" fill="#294c63" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">native execution · retries</text>
|
|
57
|
+
<text x="944" y="309" fill="#637d90" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="15">owns every side effect</text>
|
|
58
|
+
</g>
|
|
59
|
+
|
|
60
|
+
<path d="M370 220h110" stroke="#228e9b" stroke-width="4" marker-end="url(#arrow)"/>
|
|
61
|
+
<text x="425" y="204" text-anchor="middle" fill="#347485" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">bounded request</text>
|
|
62
|
+
<path d="M490 315H370" stroke="#228e9b" stroke-width="4" marker-end="url(#arrow)"/>
|
|
63
|
+
<text x="430" y="342" text-anchor="middle" fill="#347485" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">decision + correlation_id</text>
|
|
64
|
+
<path d="M790 220h120" stroke="#228e9b" stroke-width="4" marker-end="url(#arrow)"/>
|
|
65
|
+
<text x="850" y="204" text-anchor="middle" fill="#347485" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">selected capability</text>
|
|
66
|
+
<path d="M910 315H790" stroke="#228e9b" stroke-width="4" marker-end="url(#arrow)"/>
|
|
67
|
+
<text x="850" y="342" text-anchor="middle" fill="#347485" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="14" font-weight="700">execution receipt</text>
|
|
68
|
+
|
|
69
|
+
<g filter="url(#shadow)">
|
|
70
|
+
<rect x="260" y="470" width="760" height="150" rx="22" fill="url(#evidence)" stroke="#69b9aa" stroke-width="2"/>
|
|
71
|
+
<text x="640" y="515" text-anchor="middle" fill="#14505a" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="23" font-weight="750">Evidence and replay</text>
|
|
72
|
+
<text x="640" y="552" text-anchor="middle" fill="#286b73" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="17" font-weight="650">jev_record_execution · receipts · JSONL cases</text>
|
|
73
|
+
<text x="640" y="584" text-anchor="middle" fill="#4f7e82" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="15">correlation_id joins the decision to the host result; replay never executes host work</text>
|
|
74
|
+
</g>
|
|
75
|
+
<path d="M640 375v90" stroke="#228e9b" stroke-width="4" marker-end="url(#arrow)"/>
|
|
76
|
+
<path d="M1060 350v72q0 48-48 48h-22" fill="none" stroke="#228e9b" stroke-width="4" marker-end="url(#arrow)"/>
|
|
77
|
+
</svg>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 260" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">jev-layer</title>
|
|
3
|
+
<desc id="desc">Portable System-1 decision layer for agent harnesses.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
6
|
+
<stop offset="0" stop-color="#0b1220"/>
|
|
7
|
+
<stop offset="0.55" stop-color="#12233d"/>
|
|
8
|
+
<stop offset="1" stop-color="#123f4a"/>
|
|
9
|
+
</linearGradient>
|
|
10
|
+
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
|
|
11
|
+
<stop offset="0" stop-color="#66e3c4"/>
|
|
12
|
+
<stop offset="1" stop-color="#8bd5ff"/>
|
|
13
|
+
</linearGradient>
|
|
14
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
15
|
+
<feDropShadow dx="0" dy="10" stdDeviation="12" flood-color="#000" flood-opacity="0.24"/>
|
|
16
|
+
</filter>
|
|
17
|
+
</defs>
|
|
18
|
+
<rect width="1200" height="260" rx="28" fill="url(#bg)"/>
|
|
19
|
+
<circle cx="1080" cy="-15" r="220" fill="#66e3c4" opacity="0.08"/>
|
|
20
|
+
<circle cx="1120" cy="245" r="180" fill="#8bd5ff" opacity="0.08"/>
|
|
21
|
+
<g filter="url(#shadow)">
|
|
22
|
+
<rect x="72" y="64" width="132" height="132" rx="30" fill="#152e46" stroke="#66e3c4" stroke-width="2"/>
|
|
23
|
+
<path d="M105 128h66M138 95v66" stroke="url(#accent)" stroke-width="12" stroke-linecap="round"/>
|
|
24
|
+
<circle cx="138" cy="128" r="18" fill="#0b1220" stroke="#8bd5ff" stroke-width="4"/>
|
|
25
|
+
</g>
|
|
26
|
+
<text x="248" y="128" fill="#f6fbff" font-family="Inter, ui-sans-serif, system-ui, -apple-system, sans-serif" font-size="66" font-weight="750" letter-spacing="-2">jev-layer</text>
|
|
27
|
+
<text x="252" y="166" fill="#b9cce0" font-family="Inter, ui-sans-serif, system-ui, -apple-system, sans-serif" font-size="24" font-weight="500">portable System-1 decisions for agent harnesses</text>
|
|
28
|
+
<g font-family="Inter, ui-sans-serif, system-ui, -apple-system, sans-serif" font-size="15" font-weight="700" letter-spacing="1">
|
|
29
|
+
<rect x="252" y="191" width="112" height="34" rx="17" fill="#173d43" stroke="#66e3c4"/>
|
|
30
|
+
<text x="308" y="213" text-anchor="middle" fill="#9af0d9">ROUTE</text>
|
|
31
|
+
<rect x="376" y="191" width="126" height="34" rx="17" fill="#173d43" stroke="#66e3c4"/>
|
|
32
|
+
<text x="439" y="213" text-anchor="middle" fill="#9af0d9">RECEIPTS</text>
|
|
33
|
+
<rect x="514" y="191" width="112" height="34" rx="17" fill="#173d43" stroke="#66e3c4"/>
|
|
34
|
+
<text x="570" y="213" text-anchor="middle" fill="#9af0d9">REPLAY</text>
|
|
35
|
+
<rect x="638" y="191" width="130" height="34" rx="17" fill="#173d43" stroke="#8bd5ff"/>
|
|
36
|
+
<text x="703" y="213" text-anchor="middle" fill="#b9e4ff">FAIL-OPEN</text>
|
|
37
|
+
</g>
|
|
38
|
+
</svg>
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "repo_search",
|
|
4
|
-
"kind": "mcp",
|
|
5
|
-
"name": "Repository search",
|
|
6
|
-
"description": "Search repository files and symbols without changing files",
|
|
7
|
-
"permissions": ["read"],
|
|
8
|
-
"risk": "low",
|
|
9
|
-
"execution": { "target": "host-native-repository-search" }
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"id": "browser_inspect",
|
|
13
|
-
"kind": "mcp",
|
|
14
|
-
"name": "Browser inspection",
|
|
15
|
-
"description": "Open a webpage and inspect visible browser state",
|
|
16
|
-
"permissions": ["browser"],
|
|
17
|
-
"risk": "medium",
|
|
18
|
-
"execution": { "target": "host-native-browser" }
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "terminal_read",
|
|
22
|
-
"kind": "cli",
|
|
23
|
-
"name": "Read-only terminal",
|
|
24
|
-
"description": "Run a read-only shell command and return its output",
|
|
25
|
-
"permissions": ["terminal:read"],
|
|
26
|
-
"risk": "low",
|
|
27
|
-
"execution": { "target": "host-native-terminal" }
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"id": "file_write",
|
|
31
|
-
"kind": "tool",
|
|
32
|
-
"name": "File writer",
|
|
33
|
-
"description": "Modify files in the repository",
|
|
34
|
-
"permissions": ["write"],
|
|
35
|
-
"risk": "high",
|
|
36
|
-
"execution": { "target": "host-native-write" },
|
|
37
|
-
"policy": { "requires_confirmation": true }
|
|
38
|
-
}
|
|
39
|
-
]
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "repo_search",
|
|
4
|
+
"kind": "mcp",
|
|
5
|
+
"name": "Repository search",
|
|
6
|
+
"description": "Search repository files and symbols without changing files",
|
|
7
|
+
"permissions": ["read"],
|
|
8
|
+
"risk": "low",
|
|
9
|
+
"execution": { "target": "host-native-repository-search" }
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": "browser_inspect",
|
|
13
|
+
"kind": "mcp",
|
|
14
|
+
"name": "Browser inspection",
|
|
15
|
+
"description": "Open a webpage and inspect visible browser state",
|
|
16
|
+
"permissions": ["browser"],
|
|
17
|
+
"risk": "medium",
|
|
18
|
+
"execution": { "target": "host-native-browser" }
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "terminal_read",
|
|
22
|
+
"kind": "cli",
|
|
23
|
+
"name": "Read-only terminal",
|
|
24
|
+
"description": "Run a read-only shell command and return its output",
|
|
25
|
+
"permissions": ["terminal:read"],
|
|
26
|
+
"risk": "low",
|
|
27
|
+
"execution": { "target": "host-native-terminal" }
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "file_write",
|
|
31
|
+
"kind": "tool",
|
|
32
|
+
"name": "File writer",
|
|
33
|
+
"description": "Modify files in the repository",
|
|
34
|
+
"permissions": ["write"],
|
|
35
|
+
"risk": "high",
|
|
36
|
+
"execution": { "target": "host-native-write" },
|
|
37
|
+
"policy": { "requires_confirmation": true }
|
|
38
|
+
}
|
|
39
|
+
]
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema_version": 1,
|
|
3
|
-
"harness": "example",
|
|
4
|
-
"intent": "Find where the routing decision is implemented in this repository",
|
|
5
|
-
"context": {
|
|
6
|
-
"workspace": "jev-layer",
|
|
7
|
-
"api_key": "must-not-reach-provider"
|
|
8
|
-
},
|
|
9
|
-
"actor_permissions": ["read"],
|
|
10
|
-
"capabilities": [
|
|
11
|
-
{
|
|
12
|
-
"id": "repo_search",
|
|
13
|
-
"kind": "mcp",
|
|
14
|
-
"name": "Repository search",
|
|
15
|
-
"description": "Search repository files and symbols without changing files",
|
|
16
|
-
"permissions": ["read"],
|
|
17
|
-
"risk": "low"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"id": "file_write",
|
|
21
|
-
"kind": "tool",
|
|
22
|
-
"name": "File writer",
|
|
23
|
-
"description": "Modify files in the repository",
|
|
24
|
-
"permissions": ["write"],
|
|
25
|
-
"risk": "high"
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"harness": "example",
|
|
4
|
+
"intent": "Find where the routing decision is implemented in this repository",
|
|
5
|
+
"context": {
|
|
6
|
+
"workspace": "jev-layer",
|
|
7
|
+
"api_key": "must-not-reach-provider"
|
|
8
|
+
},
|
|
9
|
+
"actor_permissions": ["read"],
|
|
10
|
+
"capabilities": [
|
|
11
|
+
{
|
|
12
|
+
"id": "repo_search",
|
|
13
|
+
"kind": "mcp",
|
|
14
|
+
"name": "Repository search",
|
|
15
|
+
"description": "Search repository files and symbols without changing files",
|
|
16
|
+
"permissions": ["read"],
|
|
17
|
+
"risk": "low"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "file_write",
|
|
21
|
+
"kind": "tool",
|
|
22
|
+
"name": "File writer",
|
|
23
|
+
"description": "Modify files in the repository",
|
|
24
|
+
"permissions": ["write"],
|
|
25
|
+
"risk": "high"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "jev-layer",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"description": "Host-owned Jev capability routing through the standalone jev-layer core",
|
|
5
|
-
"author": { "name": "Local Jev Layer" },
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"keywords": ["jev", "routing", "decision", "mcp"],
|
|
8
|
-
"skills": "./skills/",
|
|
9
|
-
"mcpServers": "./.mcp.json",
|
|
10
|
-
"interface": {
|
|
11
|
-
"displayName": "Jev Layer",
|
|
12
|
-
"shortDescription": "Bounded capability decisions without host execution",
|
|
13
|
-
"longDescription": "Routes a closed candidate set and leaves approvals and execution to Codex.",
|
|
14
|
-
"developerName": "Local Jev Layer",
|
|
15
|
-
"category": "Developer Tools",
|
|
16
|
-
"capabilities": ["Decision routing"],
|
|
17
|
-
"defaultPrompt": ["Use Jev only for bounded capability routing; keep execution and approvals in Codex."]
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "jev-layer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Host-owned Jev capability routing through the standalone jev-layer core",
|
|
5
|
+
"author": { "name": "Local Jev Layer" },
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": ["jev", "routing", "decision", "mcp"],
|
|
8
|
+
"skills": "./skills/",
|
|
9
|
+
"mcpServers": "./.mcp.json",
|
|
10
|
+
"interface": {
|
|
11
|
+
"displayName": "Jev Layer",
|
|
12
|
+
"shortDescription": "Bounded capability decisions without host execution",
|
|
13
|
+
"longDescription": "Routes a closed candidate set and leaves approvals and execution to Codex.",
|
|
14
|
+
"developerName": "Local Jev Layer",
|
|
15
|
+
"category": "Developer Tools",
|
|
16
|
+
"capabilities": ["Decision routing"],
|
|
17
|
+
"defaultPrompt": ["Use Jev only for bounded capability routing; keep execution and approvals in Codex."]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mcpServers": {
|
|
3
|
-
"jev": {
|
|
4
|
-
"type": "stdio",
|
|
5
|
-
"command": "node",
|
|
6
|
-
"args": ["./run-mcp.mjs"],
|
|
7
|
-
"cwd": ".",
|
|
8
|
-
"env_vars": ["JEV_LAYER_ROOT", "JEV_LAYER_PROVIDER", "OPENROUTER_API_KEY"]
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"jev": {
|
|
4
|
+
"type": "stdio",
|
|
5
|
+
"command": "node",
|
|
6
|
+
"args": ["./run-mcp.mjs"],
|
|
7
|
+
"cwd": ".",
|
|
8
|
+
"env_vars": ["JEV_LAYER_ROOT", "JEV_LAYER_PROVIDER", "OPENROUTER_API_KEY"]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
When this adapter is enabled, use `jev_route` only for bounded closed-set capability routing. The tool returns an identifier; Codex owns all execution and approvals. On fallback, low confidence, malformed response, unavailable capability, or timeout, continue with normal Codex planning. Never send secrets or full transcripts to Jev.
|
|
1
|
+
When this adapter is enabled, use `jev_route` only for bounded closed-set capability routing. The tool returns an identifier; Codex owns all execution and approvals. On fallback, low confidence, malformed response, unavailable capability, or timeout, continue with normal Codex planning. Never send secrets or full transcripts to Jev.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { dirname, resolve } from "node:path";
|
|
2
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
-
|
|
4
|
-
const pluginRoot = dirname(fileURLToPath(import.meta.url));
|
|
5
|
-
const projectRoot = process.env.JEV_LAYER_ROOT
|
|
6
|
-
? resolve(process.env.JEV_LAYER_ROOT)
|
|
7
|
-
: resolve(pluginRoot, "../..");
|
|
8
|
-
|
|
9
|
-
await import(resolve(projectRoot, "src/mcp-server.mjs"));
|
|
1
|
+
import { dirname, resolve } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
const pluginRoot = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
const projectRoot = process.env.JEV_LAYER_ROOT
|
|
6
|
+
? resolve(process.env.JEV_LAYER_ROOT)
|
|
7
|
+
: resolve(pluginRoot, "../..");
|
|
8
|
+
|
|
9
|
+
await import(resolve(projectRoot, "src/mcp-server.mjs"));
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: jev-route
|
|
3
|
-
description: Use Jev for one bounded capability choice when a closed candidate set is already available. Keep permissions, approvals, execution, and recovery in Codex.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Jev route
|
|
7
|
-
|
|
8
|
-
Use the `jev_route` MCP tool only when the request can be expressed as one bounded choice among supplied capabilities.
|
|
9
|
-
|
|
10
|
-
1. Build a small candidate list from capabilities Codex can already execute.
|
|
11
|
-
2. Include only non-secret intent, candidate metadata, and the minimum context needed.
|
|
12
|
-
3. Call `jev_route` once.
|
|
13
|
-
4. Treat `fallback`, `no_decision`, and `needs_confirmation` as normal outcomes.
|
|
14
|
-
5. Execute `selected` only through the native Codex capability and its existing approval gate.
|
|
15
|
-
6. Never interpret a Jev response as permission to bypass Codex policy.
|
|
16
|
-
|
|
17
|
-
Do not use Jev for open-ended planning, coding, research, recovery, or arbitrary tool execution.
|
|
1
|
+
---
|
|
2
|
+
name: jev-route
|
|
3
|
+
description: Use Jev for one bounded capability choice when a closed candidate set is already available. Keep permissions, approvals, execution, and recovery in Codex.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Jev route
|
|
7
|
+
|
|
8
|
+
Use the `jev_route` MCP tool only when the request can be expressed as one bounded choice among supplied capabilities.
|
|
9
|
+
|
|
10
|
+
1. Build a small candidate list from capabilities Codex can already execute.
|
|
11
|
+
2. Include only non-secret intent, candidate metadata, and the minimum context needed.
|
|
12
|
+
3. Call `jev_route` once.
|
|
13
|
+
4. Treat `fallback`, `no_decision`, and `needs_confirmation` as normal outcomes.
|
|
14
|
+
5. Execute `selected` only through the native Codex capability and its existing approval gate.
|
|
15
|
+
6. Never interpret a Jev response as permission to bypass Codex policy.
|
|
16
|
+
|
|
17
|
+
Do not use Jev for open-ended planning, coding, research, recovery, or arbitrary tool execution.
|