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.
Files changed (83) hide show
  1. package/CHANGELOG.md +45 -34
  2. package/CONTRIBUTING.md +146 -146
  3. package/LICENSE +21 -21
  4. package/README.md +123 -126
  5. package/README.ru.md +138 -117
  6. package/README.zh-CN.md +137 -117
  7. package/RELEASE.md +53 -53
  8. package/SECURITY.md +56 -56
  9. package/bin/jev.mjs +213 -213
  10. package/config/codex.mcp.toml +8 -8
  11. package/config/generic-mcp.json +13 -13
  12. package/config/hermes.mcp.yaml +9 -9
  13. package/config/jev.example.json +22 -22
  14. package/config/omp.mcp.json +14 -14
  15. package/config/providers.env.example +13 -13
  16. package/docs/AGENT-IMPLEMENTATION.md +250 -0
  17. package/docs/COMPATIBILITY.md +15 -15
  18. package/docs/HERMES-LOCAL-AGENT-HANDOFF.ru.md +177 -0
  19. package/docs/PROVIDERS.md +67 -0
  20. package/docs/SCHEMA-VERSIONING.md +96 -94
  21. package/docs/architecture.svg +77 -0
  22. package/docs/jev-layer-banner.svg +38 -0
  23. package/examples/capabilities.json +39 -39
  24. package/examples/route-request.json +28 -28
  25. package/integrations/codex/.codex-plugin/plugin.json +19 -19
  26. package/integrations/codex/.mcp.json +11 -11
  27. package/integrations/codex/AGENTS.md +1 -1
  28. package/integrations/codex/run-mcp.mjs +9 -9
  29. package/integrations/codex/skills/jev-route/SKILL.md +17 -17
  30. package/integrations/hermes/__init__.py +150 -51
  31. package/integrations/hermes/plugin.yaml +10 -5
  32. package/integrations/hermes/schemas.py +89 -12
  33. package/integrations/omp/extension.js +105 -105
  34. package/integrations/template/README.md +10 -10
  35. package/integrations/template/adapter.mjs +87 -87
  36. package/package.json +60 -59
  37. package/scripts/benchmark.mjs +35 -35
  38. package/scripts/browser-benchmark.mjs +92 -92
  39. package/scripts/browser-e2e.mjs +117 -117
  40. package/scripts/capability-e2e.mjs +31 -31
  41. package/scripts/clean-install-smoke.mjs +162 -162
  42. package/scripts/codex-mcp-smoke.mjs +119 -119
  43. package/scripts/context-filter-e2e.mjs +45 -45
  44. package/scripts/fail-open-smoke.mjs +120 -120
  45. package/scripts/feature-flags-smoke.mjs +46 -46
  46. package/scripts/mcp-receipt-smoke.mjs +113 -98
  47. package/scripts/model-route-report.mjs +15 -0
  48. package/scripts/openrouter-choice.mjs +59 -59
  49. package/scripts/replay-eval.mjs +124 -124
  50. package/scripts/smoke.mjs +34 -34
  51. package/scripts/supervision-e2e.mjs +138 -109
  52. package/src/browser.mjs +571 -569
  53. package/src/cli.mjs +33 -33
  54. package/src/config.mjs +85 -75
  55. package/src/context-filter.mjs +56 -56
  56. package/src/contract.mjs +72 -72
  57. package/src/discovery.mjs +65 -65
  58. package/src/hermes-adapter.mjs +123 -0
  59. package/src/mcp-server.mjs +267 -210
  60. package/src/model-route-metrics.mjs +89 -0
  61. package/src/model-routing.mjs +87 -0
  62. package/src/providers/demo.mjs +52 -52
  63. package/src/providers/index.mjs +12 -0
  64. package/src/providers/typesafe.mjs +126 -126
  65. package/src/receipts.mjs +227 -226
  66. package/src/registry.mjs +109 -109
  67. package/src/relevance-filter.mjs +99 -99
  68. package/src/route.mjs +219 -221
  69. package/src/shadow-compaction.mjs +170 -0
  70. package/src/supervision.mjs +268 -244
  71. package/test/browser.test.mjs +199 -199
  72. package/test/capability.test.mjs +54 -54
  73. package/test/context-filter.test.mjs +65 -65
  74. package/test/hermes-adapter.test.mjs +62 -0
  75. package/test/model-route-metrics.test.mjs +61 -0
  76. package/test/model-routing.test.mjs +59 -0
  77. package/test/openrouter-provider.test.mjs +55 -55
  78. package/test/provider-transports.test.mjs +205 -0
  79. package/test/providers.test.mjs +126 -0
  80. package/test/receipts.test.mjs +71 -71
  81. package/test/route.test.mjs +74 -74
  82. package/test/shadow-compaction.test.mjs +67 -0
  83. package/test/supervision.test.mjs +117 -99
@@ -0,0 +1,250 @@
1
+ # Agent implementation guide
2
+
3
+ This is the implementation brief to hand to a coding agent before integrating jev-layer into a harness. It is intentionally operational: inspect the target harness first, preserve host ownership, and prove the fallback path. Do not treat a link to this repository as permission to invent an adapter or change the host's execution model.
4
+
5
+ ## Contract in one paragraph
6
+
7
+ jev-layer is a **System-1 decision layer**, not an executor, permission system, security boundary, retry loop, or browser worker. The host owns capability discovery, the closed candidate set, permissions, approvals, native execution, retries, recovery, and final output. Jev receives bounded input, returns one bounded decision with a `correlation_id`, and records the host's result. If Jev is disabled, unavailable, invalid, inconclusive, or refused by policy, the host continues through its normal native path.
8
+
9
+ ## Before editing
10
+
11
+ 1. Identify the harness's native capability registry and native execution function.
12
+ 2. Identify the existing permission and approval checks, especially for consequential actions.
13
+ 3. Identify the host's normal fallback path and its error/retry boundaries.
14
+ 4. Read [CONTRIBUTING.md](../CONTRIBUTING.md), [SECURITY.md](../SECURITY.md), and [SCHEMA-VERSIONING.md](SCHEMA-VERSIONING.md).
15
+ 5. Confirm the harness version and transport: CLI, stdio MCP, or an existing adapter boundary.
16
+ 6. Write a short integration plan naming the exact adapter entry point and the unchanged host-owned functions.
17
+ 7. Only then edit the smallest possible adapter/configuration surface.
18
+
19
+ Do not begin by pasting the repository URL to an agent and asking it to "integrate Jev" without supplying the target harness, its native execution path, and its approval semantics.
20
+
21
+ ## Required data flow
22
+
23
+ ### 1. Build a closed capability set in the host
24
+
25
+ The host must provide only capabilities it already knows how to execute. Each candidate needs a stable id and enough metadata for bounded selection:
26
+
27
+ ```json
28
+ {
29
+ "id": "repo:search",
30
+ "kind": "tool",
31
+ "name": "Search repository",
32
+ "description": "Find text in tracked repository files",
33
+ "permissions": ["read"],
34
+ "risk": "low",
35
+ "available": true
36
+ }
37
+ ```
38
+
39
+ Do not ask Jev to discover hidden host tools. Do not pass arbitrary shell commands as capability ids. Do not expose a capability that the host cannot validate and execute through its native registry.
40
+
41
+ ### 2. Call `jev_route` with bounded input
42
+
43
+ Preserve schema version 1 and include the host-owned facts needed for the decision:
44
+
45
+ ```json
46
+ {
47
+ "schema_version": 1,
48
+ "harness": "my-harness",
49
+ "intent": "Find the implementation of the routing contract",
50
+ "context": {
51
+ "task": "repository inspection"
52
+ },
53
+ "actor_permissions": ["read"],
54
+ "capabilities": [
55
+ {
56
+ "id": "repo:search",
57
+ "kind": "tool",
58
+ "name": "Search repository",
59
+ "description": "Find text in tracked repository files",
60
+ "permissions": ["read"],
61
+ "risk": "low",
62
+ "available": true
63
+ }
64
+ ],
65
+ "policy": {
66
+ "deterministic": true
67
+ }
68
+ }
69
+ ```
70
+
71
+ Keep `intent`, `context`, and the candidate set bounded. Do not send credentials, unbounded conversation history, hidden tool descriptions, or machine-specific paths.
72
+
73
+ ### 3. Treat the response as advice, never authorization
74
+
75
+ A normal decision has this shape:
76
+
77
+ ```json
78
+ {
79
+ "schema_version": 1,
80
+ "correlation_id": "decision-id",
81
+ "status": "selected",
82
+ "selected": "repo:search",
83
+ "execution": {
84
+ "enabled": false,
85
+ "status": "not_started"
86
+ }
87
+ }
88
+ ```
89
+
90
+ The adapter must validate all of the following before execution:
91
+
92
+ - `status` permits a host action (`selected` is different from `fallback`, `no_decision`, and `needs_confirmation`);
93
+ - `selected` is non-null and exactly matches an id in the request's candidate set;
94
+ - the candidate is still available and its permissions/risk are acceptable;
95
+ - the host's current approval policy allows the action.
96
+
97
+ Never execute an id returned by Jev as a shell command, import path, URL, or arbitrary function name. Resolve it through the harness's native registry.
98
+
99
+ ### 4. Let the host approve consequential work
100
+
101
+ Jev cannot approve, elevate, or override the host. For a consequential candidate:
102
+
103
+ 1. pause after the decision;
104
+ 2. run the host's existing approval flow;
105
+ 3. if denied, do not execute and record `status: "not_started"`;
106
+ 4. if approved, execute through the native host path.
107
+
108
+ The Jev decision does not replace the harness confirmation dialog, policy engine, or permission check.
109
+
110
+ ### 5. Execute only through the native host path
111
+
112
+ The adapter must not become a second executor. Preserve the host's existing:
113
+
114
+ - capability lookup;
115
+ - permission checks;
116
+ - approval prompts;
117
+ - process/browser/tool execution;
118
+ - retry and recovery behavior;
119
+ - result shaping and user-visible output.
120
+
121
+ Jev returns a decision. The host performs the work.
122
+
123
+ ### 6. Record one receipt with the same correlation id
124
+
125
+ After the host knows what happened, call `jev_record_execution`:
126
+
127
+ ```json
128
+ {
129
+ "correlation_id": "decision-id",
130
+ "harness": "my-harness",
131
+ "capability_id": "repo:search",
132
+ "status": "completed",
133
+ "result": {
134
+ "matches": 3
135
+ },
136
+ "exit_status": 0,
137
+ "duration_ms": 12
138
+ }
139
+ ```
140
+
141
+ Use the same `correlation_id` from `jev_route`. Use:
142
+
143
+ - `completed` when native execution finished successfully;
144
+ - `failed` when native execution ran and failed;
145
+ - `not_started` when approval, policy, or fail-open handling prevented execution.
146
+
147
+ Bound results and errors before recording them. Never write secrets or full untrusted logs into receipts.
148
+
149
+ ### 7. Preserve fail-open behavior
150
+
151
+ The following conditions must return control to the host's ordinary path without guessing a capability:
152
+
153
+ - Jev is disabled by configuration;
154
+ - the MCP/CLI process is unavailable or times out;
155
+ - the provider returns an error or malformed response;
156
+ - the decision is `fallback`, `no_decision`, or otherwise unusable;
157
+ - the selected id is not in the closed candidate set;
158
+ - permissions or approval reject the action.
159
+
160
+ A Jev failure is not permission to execute. Do not add an adapter retry loop that changes the host's existing retry semantics.
161
+
162
+ ## Installing and wiring the package
163
+
164
+ For a published local CLI:
165
+
166
+ ```sh
167
+ npm install --global jev-layer
168
+ jev init --project /path/to/workspace
169
+ jev add generic --project /path/to/workspace
170
+ jev doctor --project /path/to/workspace
171
+ ```
172
+
173
+ For a stdio MCP server:
174
+
175
+ ```sh
176
+ jev mcp
177
+ ```
178
+
179
+ The generated generic adapter uses the `jev mcp` command. Keep the adapter configuration in the project/workspace where the harness owns it; do not overwrite global harness configuration. Use `JEV_LAYER_PROVIDER=demo` for offline deterministic development. Keep OpenRouter or TypeSafe credentials in the process environment or another user-owned secret store.
180
+
181
+ For an existing harness, copy the smallest relevant example from `integrations/` and adapt its transport. Do not copy an integration wholesale without checking the harness's actual registry, approval, and execution APIs.
182
+
183
+ ## Copy-paste handoff for a coding agent
184
+
185
+ Use this prompt with the guide and the target harness details:
186
+
187
+ ```text
188
+ Implement jev-layer as a thin System-1 decision layer in this harness.
189
+
190
+ Read docs/AGENT-IMPLEMENTATION.md first. Then inspect the harness's native
191
+ capability registry, permission checks, approval flow, execution function,
192
+ retry/recovery boundaries, and existing MCP/CLI integration point.
193
+
194
+ Target harness: <name and version>
195
+ Target integration point: <file/function/config>
196
+ Native execution function: <file/function>
197
+ Approval authority: <file/function>
198
+ Normal fallback path: <file/function>
199
+
200
+ Requirements:
201
+ - Build a closed capabilities[] set from the host registry.
202
+ - Call jev_route with schema_version: 1, bounded intent/context,
203
+ actor_permissions, capabilities, and policy.
204
+ - Validate status, selected id, availability, permissions, and approval in
205
+ the host before execution.
206
+ - Resolve selected ids through the native registry; never shell out to ids
207
+ returned by Jev and never let Jev execute host work.
208
+ - Preserve the existing host fallback path when Jev is disabled, unavailable,
209
+ invalid, inconclusive, or rejected.
210
+ - Call jev_record_execution with the same correlation_id after the host knows
211
+ the result.
212
+ - Add offline tests for selected execution, fail-open, unknown-id rejection,
213
+ approval denial, and receipt correlation.
214
+ - Do not add provider credentials, global config writes, hidden capability
215
+ discovery, arbitrary command execution, or unrelated runtime features.
216
+
217
+ Before changing code, show the files/symbols you will touch. After changing
218
+ code, report the exact native execution path preserved and the verification
219
+ commands/results.
220
+ ```
221
+
222
+ Replace every `<...>` placeholder with facts from the target harness. Do not leave the agent to infer them from a generic repository link.
223
+
224
+ ## Minimum verification matrix
225
+
226
+ An implementation is not complete until it proves these observable behaviors:
227
+
228
+ | Scenario | Required result |
229
+ | --- | --- |
230
+ | Valid low-risk selection | Host executes the matching native capability once. |
231
+ | Unknown or stale selected id | Host does not execute; normal fallback remains available. |
232
+ | `needs_confirmation` | Host approval is requested before execution. |
233
+ | Approval denied | No host execution; receipt is `not_started`. |
234
+ | Jev disabled/unavailable/error | Normal host path continues without guessed selection. |
235
+ | Native execution failure | Receipt is `failed` with the same `correlation_id`. |
236
+ | Successful native execution | Receipt is `completed` with bounded result/timing metadata. |
237
+ | Replay evaluation | Routing/receipt cases replay without host execution. |
238
+
239
+ Run the existing project checks plus the matching adapter smoke fixture. At minimum, a jev-layer integration should preserve the checks in `CONTRIBUTING.md` and add a harness-specific offline fixture; provider credentials are not required for ordinary CI.
240
+
241
+ ## Common incorrect implementations
242
+
243
+ - **Calling Jev after executing the tool.** Routing must happen before the host action.
244
+ - **Passing every hidden tool to Jev.** Send only a closed, host-owned candidate set.
245
+ - **Treating `selected` as authorization.** The host still validates permissions and approval.
246
+ - **Executing the returned id directly.** Map it through the native registry; never use it as a command.
247
+ - **Replacing fail-open with a retry loop.** Return to the existing host path.
248
+ - **Letting Jev discover or mutate global config.** Discovery and configuration remain explicit and user-owned.
249
+ - **Adding provider calls to ordinary CI.** Use the deterministic `demo` provider and injected fixtures.
250
+ - **Reporting only that an adapter was added.** Show the preserved execution path, receipt correlation, and fallback evidence.
@@ -1,15 +1,15 @@
1
- # Harness compatibility baseline
2
-
3
- [English](../README.md) | [Русский](../README.ru.md) | [简体中文](../README.zh-CN.md)
4
-
5
- This is the first-release compatibility baseline observed on 2026-09-19. It records the installed harness versions used for the release-preparation checks; it is not a claim that every provider/model combination was exercised.
6
-
7
- | Harness | Version observed | Release-preparation coverage |
8
- | --- | --- | --- |
9
- | OMP | `18.2.6` | `omp --version`; OMP extension contract and host-owned execution path reviewed; Jev core smoke uses the same MCP/CLI contract. |
10
- | Hermes | `0.21.3` (`upstream b675e6de`) | `hermes --version`; Python adapter syntax/contract reviewed; Jev core smoke uses the same CLI/MCP contract. |
11
- | Codex CLI | `0.155.1` | `codex --version`; Codex MCP transport fixture and host-execution ownership path reviewed. The fixture does not invoke a Codex model. |
12
-
13
- The adapters are thin and target the stable v1 contract documented in [CONTRIBUTING.md](../CONTRIBUTING.md) and [SCHEMA-VERSIONING.md](SCHEMA-VERSIONING.md). Full interactive harness/model/provider coverage is environment-specific and is not required for ordinary PR CI.
14
-
15
- When a public release supports a different harness version, update this table, rerun the adapter/transport checks, and document any compatibility change in `CHANGELOG.md` before tagging.
1
+ # Harness compatibility baseline
2
+
3
+ [English](../README.md) | [Русский](../README.ru.md) | [简体中文](../README.zh-CN.md)
4
+
5
+ This is the first-release compatibility baseline observed on 2026-09-19. It records the installed harness versions used for the release-preparation checks; it is not a claim that every provider/model combination was exercised.
6
+
7
+ | Harness | Version observed | Release-preparation coverage |
8
+ | --- | --- | --- |
9
+ | OMP | `18.2.6` | `omp --version`; OMP extension contract and host-owned execution path reviewed; Jev core smoke uses the same MCP/CLI contract. |
10
+ | Hermes | `0.21.3` (`upstream b675e6de`) | `hermes --version`; Python adapter syntax/contract reviewed; Jev core smoke uses the same CLI/MCP contract. |
11
+ | Codex CLI | `0.155.1` | `codex --version`; Codex MCP transport fixture and host-execution ownership path reviewed. The fixture does not invoke a Codex model. |
12
+
13
+ The adapters are thin and target the stable v1 contract documented in [CONTRIBUTING.md](../CONTRIBUTING.md) and [SCHEMA-VERSIONING.md](SCHEMA-VERSIONING.md). Full interactive harness/model/provider coverage is environment-specific and is not required for ordinary PR CI.
14
+
15
+ When a public release supports a different harness version, update this table, rerun the adapter/transport checks, and document any compatibility change in `CHANGELOG.md` before tagging.
@@ -0,0 +1,177 @@
1
+ # Hermes integration: handoff для локального агента
2
+
3
+ Этот документ описывает **текущую рабочую интеграцию** `jev-layer` в Hermes. Он нужен локальному агенту, чтобы сначала понять границы и точки входа, а не повторно «интегрировать Jev» через глобальный конфиг, произвольные shell-команды или второй executor.
4
+
5
+ ## Что уже установлено
6
+
7
+ - Исходный репозиторий: `/home/hermes/jev-layer`.
8
+ - Активная plugin-копия Hermes: `~/.hermes/plugins/jev-layer`.
9
+ - Plugin регистрирует ровно шесть tools:
10
+ - `jev_route`;
11
+ - `jev_record_execution`;
12
+ - `jev_supervise`;
13
+ - `jev_browser_step`;
14
+ - `jev_shadow_compaction`;
15
+ - `jev_model_route`.
16
+ - Replay evidence активного профиля: `~/.hermes/jev-layer/replay/cases.jsonl`.
17
+ - Gateway загружает Python plugin при старте. После изменения `integrations/hermes/*`, `plugin.yaml` или списка tools нужен пользовательский `/restart` gateway.
18
+
19
+ Не путай surfaces:
20
+
21
+ ```text
22
+ /home/hermes/jev-layer source checkout, тесты и документация
23
+ ~/.hermes/plugins/jev-layer установленная plugin-копия текущего профиля
24
+ ~/.hermes/jev-layer/replay/cases.jsonl profile-scoped evidence, не source artifact
25
+ ~/.hermes/config.yaml глобальный Hermes config; не менять для этой plugin без явного задания
26
+ ```
27
+
28
+ ## Главный принцип
29
+
30
+ ```text
31
+ Hermes registry/permissions/approval/executor/recovery
32
+ │ closed, bounded input
33
+ ▼
34
+ jev-layer decision
35
+ │ correlation_id, advice only
36
+ ▼
37
+ Hermes validates → native execution → jev_record_execution → JSONL evidence
38
+ ```
39
+
40
+ Jev **никогда** не получает право исполнять tool, shell, URL или browser action. Любое решение — advisory. Hermes остаётся владельцем discovery, policy, approval, native execution, retry, recovery и финального ответа.
41
+
42
+ Если Jev выключен, недоступен, даёт невалидный ответ или низкую уверенность, текущий normal Hermes path продолжается. Не добавляй обходной executor и не меняй retry semantics.
43
+
44
+ ## Файловая карта
45
+
46
+ | Зачем | Файл |
47
+ | --- | --- |
48
+ | Hermes tool registration + profile-scoped secret bridge | `integrations/hermes/__init__.py` |
49
+ | JSON schemas шести tool surfaces | `integrations/hermes/schemas.py` |
50
+ | Plugin manifest | `integrations/hermes/plugin.yaml`, `plugin.yaml` |
51
+ | Один JSONL request/response adapter process | `src/hermes-adapter.mjs` |
52
+ | Общая bounded routing contract | `src/route.mjs`, `src/contract.mjs` |
53
+ | Receipt/replay JSONL format | `src/receipts.mjs` |
54
+ | Browser action space, progress и recovery | `src/browser.mjs` |
55
+ | Model recommendation | `src/model-routing.mjs` |
56
+ | Model-route evidence report | `src/model-route-metrics.mjs`, `scripts/model-route-report.mjs` |
57
+ | Context keep/drop report | `src/shadow-compaction.mjs` |
58
+ | Work-state judgement | `src/supervision.mjs` |
59
+ | Harness-neutral integration contract | `docs/AGENT-IMPLEMENTATION.md` |
60
+
61
+ ## Как работают tools
62
+
63
+ ### `jev_route`
64
+
65
+ Hermes сначала собирает **закрытый** `capabilities[]` из своего registry. Jev выбирает один известный id. До исполнения Hermes снова проверяет: `status`, точное совпадение id, availability, permission, risk и approval. После результата используется `jev_record_execution` с тем же `correlation_id`.
66
+
67
+ Нельзя передавать в candidates hidden tools, raw shell command, credential, неограниченную историю или capability, для которой у Hermes нет native executor.
68
+
69
+ ### `jev_record_execution`
70
+
71
+ Принимает результат уже выполненного/отклонённого host action. `correlation_id` должен принадлежать decision того же gateway process. Статусы: `completed`, `failed`, `not_started`.
72
+
73
+ Receipt — evidence, не источник авторизации. В `result` нельзя писать токены, пароли, номера карт и полный неочищенный лог.
74
+
75
+ ### `jev_model_route`
76
+
77
+ Возвращает рекомендацию одного из **host-declared** `models[]`. Всегда `route_mode: "shadow"`; он не меняет Hermes provider, model или reasoning effort.
78
+
79
+ Когда host закончил реальный model call, он записывает outcome через `jev_record_execution`:
80
+
81
+ ```json
82
+ {
83
+ "correlation_id": "из jev_model_route",
84
+ "capability_id": "recommended model id",
85
+ "status": "completed",
86
+ "result": {
87
+ "model_route": {
88
+ "actual_model_id": "фактически использованный id",
89
+ "retry_count": 0,
90
+ "outcome": "verified"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Отчёт только читает receipts:
97
+
98
+ ```bash
99
+ npm run model-route:report -- ~/.hermes/jev-layer/replay/cases.jsonl
100
+ ```
101
+
102
+ Пока не накоплены репрезентативные outcomes/retries/latency/cost, **не включать** auto-switching моделей.
103
+
104
+ ### `jev_browser_step`
105
+
106
+ Принимает только snapshot, который сделал host: `url`, visible text, targets, tabs, scroll и progress. Возвращает один bounded action: scroll, switch tab, visible link navigation, click, native select или handoff.
107
+
108
+ - `scroll` и `switch_tab` могут быть исполнены только через native Hermes browser executor.
109
+ - `click`, `select`, `navigate` требуют host approval.
110
+ - `submit`, login, payment, delete, секретный ввод и `TYPE_TEXT` не являются быстрым Jev execution path.
111
+ - Progress не даёт повторять уже выполненный target и блокирует повторный scroll без измеримого состояния страницы.
112
+ - После каждого host шага можно записать routing case и execution receipt; это позволяет replay без повторного browser execution.
113
+
114
+ `browser-use/jev-ultrafast` был использован как архитектурный reference (динамическая индексированная action space), но его cloud/browser worker **не установлен и не запущен**. Не подменяй Hermes browser security model его executor'ом.
115
+
116
+ ### `jev_shadow_compaction`
117
+
118
+ Возвращает консервативный report keep/drop для переданного context. Не меняет prompt, не удаляет сообщения и не заменяет host compaction. Pinned requirements, paths, errors и commands сохраняются без provider review; provider error удерживает всё.
119
+
120
+ ### `jev_supervise`
121
+
122
+ Делает bounded judgement о work state. Hermes, не Jev, преобразует его в `continue`, `verify`, `retry`, `finish` или `escalate`. Contradictory evidence не может закончиться `finish`.
123
+
124
+ ## Secrets и providers
125
+
126
+ `integrations/hermes/__init__.py` получает `OPENROUTER_API_KEY` только через Hermes profile-scoped secret store (`agent.secret_scope.get_secret`). Ключ передаётся лишь в короткоживущий локальный Node adapter; не возвращается в tool output и не логируется.
127
+
128
+ Для локальных/offline tests используй `provider: "demo"`. Provider-backed проверки — отдельные, opt-in; ключи никогда не клади в repo, plugin manifest, test fixture или обычный shell history.
129
+
130
+ ## Безопасный change workflow
131
+
132
+ 1. Прочитай этот документ и `docs/AGENT-IMPLEMENTATION.md`.
133
+ 2. Проверь target surface: source checkout, installed plugin copy, active profile или global config.
134
+ 3. Измени source в `/home/hermes/jev-layer` и сначала добавь/измени offline test.
135
+ 4. Запусти узкий test, затем полный suite.
136
+ 5. Синхронизируй **только нужные** source files в `~/.hermes/plugins/jev-layer`.
137
+ 6. Запусти `hermes plugins doctor jev-layer`.
138
+ 7. Если менялась регистрация/handler/schema/manifest, попроси пользователя о `/restart`.
139
+ 8. После restart проверь живой gateway tool path и read back exact receipt/report.
140
+ 9. Не делай `git push`, npm publish, GitHub release или изменение глобального Hermes config без отдельной команды пользователя.
141
+
142
+ ## Проверки
143
+
144
+ Из source checkout:
145
+
146
+ ```bash
147
+ npm test
148
+ npm run receipt:mcp-smoke
149
+ npm run browser:e2e
150
+ npm run model-route:report -- /tmp/nonexistent-cases.jsonl
151
+ python3 -m py_compile integrations/hermes/__init__.py integrations/hermes/schemas.py
152
+ git diff --check
153
+ hermes plugins doctor jev-layer
154
+ ```
155
+
156
+ Текущее доказанное состояние: `npm test` — 35/35; MCP receipt smoke и browser fixture E2E проходят; gateway-live model route был записан и успешно связан с execution receipt/report. Это не доказательство автоматического роутинга моделей и не утверждение о real-browser speedup.
157
+
158
+ ## Готовый prompt локальному агенту
159
+
160
+ ```text
161
+ Работай только с jev-layer в указанном target surface. Сначала прочитай:
162
+ - docs/HERMES-LOCAL-AGENT-HANDOFF.ru.md
163
+ - docs/AGENT-IMPLEMENTATION.md
164
+
165
+ Сохрани host ownership: Jev даёт bounded advisory decision; Hermes владеет registry,
166
+ permissions, approval, execution, retry/recovery и финальным результатом. Не добавляй
167
+ автоматическое переключение моделей, browser executor, глобальный config write, provider
168
+ credential или network publication без отдельного явного требования.
169
+
170
+ Перед изменением назови source files, installed plugin files и gateway impact. Используй TDD:
171
+ сначала узкий offline test, затем implementation, потом npm test + релевантные smoke tests.
172
+ Если touch'нуты registration/handler/schema/manifest, синхронизируй plugin copy, прогоняй
173
+ hermes plugins doctor jev-layer и попроси /restart. После рестарта сделай live tool call,
174
+ запиши/прочитай exact receipt и только затем заявляй, что integration активна.
175
+
176
+ Не делай git push, npm publish, release или удаление replay/artifact без отдельной команды.
177
+ ```
@@ -0,0 +1,67 @@
1
+ # Routing providers
2
+
3
+ CLI, stdio MCP, and the Hermes/OMP adapters use the same three providers. Routing, supervision, and browser decisions share provider resolution. The host still owns execution and approval.
4
+
5
+ | Provider | Default endpoint | Default model | Credentials |
6
+ | --- | --- | --- | --- |
7
+ | `demo` | None; deterministic word matching, no HTTP | `jev-demo` | None |
8
+ | `openrouter` | `https://openrouter.ai/api/alpha/decisions` | `typesafe/jev-1.13` | `OPENROUTER_API_KEY` |
9
+ | `typesafe` | `https://api.typesafe.ai/v1/systemone` | `jev-latest` | `TYPESAFE_API_KEY` |
10
+
11
+ Both remote providers send `{ model, state, questions }` with a Choice question and Bearer authentication. They use the [OpenRouter Decisions API](https://openrouter.ai/docs/api/api-reference/alphadecisions/submit-a-decisions-questions-and-answers-request) and the [official TypeSafe API](https://docs.typesafe.ai/api), respectively.
12
+
13
+ ## Select a provider
14
+
15
+ For a stdio MCP process, export the selected provider's API key through your secret store into the harness environment, then choose one command:
16
+
17
+ ```sh
18
+ JEV_LAYER_PROVIDER=demo jev mcp
19
+ JEV_LAYER_PROVIDER=openrouter jev mcp
20
+ JEV_LAYER_PROVIDER=typesafe jev mcp
21
+ ```
22
+
23
+ For a single CLI request from the repository root:
24
+
25
+ ```sh
26
+ jev cli --provider demo --input examples/route-request.json
27
+ jev cli --provider openrouter --input examples/route-request.json
28
+ jev cli --provider typesafe --input examples/route-request.json
29
+ ```
30
+
31
+ Selection precedence is: request `provider` → CLI `--provider` (CLI only) → `JEV_LAYER_PROVIDER` → `.jev/config.json` `provider` → `demo`. MCP launcher `env` entries count as process environment; update them when switching providers. Hermes and OMP delegate this choice to the CLI instead of forcing `demo`. The Hermes adapter's default process timeout is 10 seconds, allowing either provider's HTTP timeout to complete; `JEV_LAYER_TIMEOUT_S` overrides it.
32
+
33
+ `jev add <harness> --provider typesafe` generates configuration for TypeSafe in the target workspace. Use `--provider openrouter` or `--provider demo` for the other modes. Keep keys outside generated configuration.
34
+
35
+ ## Endpoints, models, and custom environment names
36
+
37
+ - TypeSafe: `TYPESAFE_ENDPOINT`, `TYPESAFE_MODEL`.
38
+ - OpenRouter: `OPENROUTER_DECISIONS_ENDPOINT`, `OPENROUTER_DECISIONS_MODEL`; optional attribution headers use `OPENROUTER_HTTP_REFERER` and `OPENROUTER_APP_TITLE`.
39
+ - Endpoints are complete request URLs, including `/v1/systemone` or `/api/alpha/decisions`.
40
+ - Default HTTP timeouts are 2 seconds for TypeSafe and 5 seconds for OpenRouter. There are no provider retries; failures return control to the host.
41
+
42
+ The CLI and MCP read `.jev/config.json` from their working directory. `JEV_CONFIG` selects another file. To use secret-store-specific environment names, set only their names in the config:
43
+
44
+ ```json
45
+ {
46
+ "provider": "typesafe",
47
+ "providers": {
48
+ "typesafe": {
49
+ "api_key_env": "MY_TYPESAFE_KEY",
50
+ "endpoint_env": "MY_TYPESAFE_ENDPOINT",
51
+ "model_env": "MY_TYPESAFE_MODEL"
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ Omitted fields retain the default environment names. A missing configured key returns `fallback` without an HTTP call, even if `TYPESAFE_API_KEY` is set. The same mapping is supported under `providers.openrouter`.
58
+
59
+ ## Verification
60
+
61
+ `jev doctor` checks configuration and key presence; it does not run inference or validate a key with the provider.
62
+
63
+ ```sh
64
+ node --test test/providers.test.mjs test/provider-transports.test.mjs
65
+ ```
66
+
67
+ These offline checks cover all three provider selections, CLI/MCP precedence, custom environment names, Hermes/OMP transport, and fail-open behavior. Remote-provider requests use injected responses or a loopback HTTP server with fixture credentials. No paid inference, agent model, or real browser is invoked. Live provider/account availability requires a separately configured environment.