@pablozrrrr/jevguard 0.2.3 → 0.3.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/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # JevGuard
2
2
 
3
3
  > **Semantic policy engine for coding agents.**
4
+ >
5
+ > JevGuard reviews every change an AI coding agent makes against the rules of your
6
+ > repository, written in plain Markdown, and reports `PASS`, `WARN`, or `FAIL` per
7
+ > rule. It runs in the background for OpenCode and Claude Code, never blocks the
8
+ > agent, and never edits your code.
4
9
 
5
10
  ![JevGuard: semantic policy engine for coding agents](https://raw.githubusercontent.com/pablozr/JevGuard/main/27b864b2-3f64-4211-99dd-26764c549d03.png)
6
11
 
@@ -8,6 +13,30 @@ JevGuard checks the code an agent just changed against the policies that matter
8
13
  your repository. It uses Jev for a narrow semantic judgment per rule, then applies
9
14
  your local deterministic gate to return `PASS`, `WARN`, or `FAIL`.
10
15
 
16
+ | Host | Package | Status |
17
+ | --- | --- | --- |
18
+ | [OpenCode](https://opencode.ai) | `@pablozrrrr/jevguard` | Available, targets OpenCode `1.18.32` |
19
+ | [Claude Code](https://claude.com/claude-code) | `@pablozrrrr/jevguard-claude-code` | Available through this repository's plugin marketplace |
20
+ | Codex | — | Planned |
21
+
22
+ ## Quick start
23
+
24
+ ```sh
25
+ # 1. Store your Jev key in the OS credential store (shared by both hosts)
26
+ bunx --package @pablozrrrr/jevguard jevguard login
27
+
28
+ # 2a. OpenCode: register the plugin in opencode.json
29
+ bunx --package @pablozrrrr/jevguard jevguard install
30
+
31
+ # 2b. Claude Code: install from the marketplace
32
+ claude plugin marketplace add pablozr/JevGuard
33
+ claude plugin install jevguard@jevguard
34
+ ```
35
+
36
+ Then add your rules to `.jev/rules.md` (in OpenCode, the bundled `jev-init` skill can
37
+ bootstrap them) and keep working with your agent as usual. Details are in
38
+ [Install](#install) and the [Claude Code guide](./docs/configuration.md#claude-code).
39
+
11
40
  ```text
12
41
  agent completes a turn
13
42
  ↓
@@ -27,13 +56,20 @@ specific policy, and leaves planning, code generation, and correction with the
27
56
  coding agent.
28
57
 
29
58
  > [!WARNING]
30
- > JevGuard is in active development. The current release targets OpenCode `1.18.32`
31
- > and evaluates every rule block declared in `.jev/rules.md` plus the `SCOPE-CREEP`
32
- > and `COMPLEXITY` built-ins. Reviews are background and observe-only: they report
33
- > results but never alter the agent context or block a task. When remediation is
34
- > enabled and a review has any `FAIL`, the plugin asks a hidden `jevguard-proposer`
35
- > subagent for a proposal in an isolated child session and shows a generic toast; the
36
- > proposer never edits code.
59
+ > JevGuard is in active development. The OpenCode plugin targets OpenCode `2.2.x`
60
+ > (minimum `2.2.2`, `>=2.2.2 <2.3`) through the V2 plugin API and evaluates every rule
61
+ > block declared in `.jev/rules.md` plus the `SCOPE-CREEP` and `COMPLEXITY` built-ins.
62
+ > Reviews are background and observe-only: they report results but never alter the
63
+ > agent context or block a task. When remediation is enabled and a review has any
64
+ > `FAIL`, the plugin asks for a proposal in an isolated, deny-all child session; the
65
+ > proposal never edits code. See [OpenCode 2.2.x limitations](#opencode-22x-limitations).
66
+ > On Claude Code and OpenCode, a user who opts in with `mode: remediate` in their own
67
+ > `claude-code.yaml` or `opencode.yaml` gets a bounded chain of at most 3 visible
68
+ > correction messages to the agent; see
69
+ > [Remediation proposals](docs/configuration.md#remediation-proposals) and
70
+ > [OpenCode `mode: remediate`](docs/configuration.md#opencode-mode-remediate-bounded-chain).
71
+ > The Claude Code plugin is distributed through this repository's marketplace; see the
72
+ > [Claude Code guide](./docs/configuration.md#claude-code).
37
73
 
38
74
  ## Why JevGuard
39
75
 
@@ -165,9 +201,12 @@ concurrency limit caps the plugin instance at two Jev requests in flight, counti
165
201
  built-in batch as a single request. Results join the same aggregate in a fixed order:
166
202
  rules in source order, then `SCOPE-CREEP`, then `COMPLEXITY`.
167
203
 
168
- Reviews run in the background. The idle event returns as soon as the serialized
169
- attribution step is scheduled; policy reads, Jev calls, and presentation never sit on
170
- the agent's critical path.
204
+ Reviews run in the background. The unit of review is one session execution, from
205
+ `session.execution.started` to `session.execution.succeeded`; the event handler returns
206
+ as soon as the serialized attribution step is scheduled, so policy reads, Jev calls,
207
+ and presentation never sit on the agent's critical path. An `interrupted` or `failed`
208
+ execution is not reviewed: the plugin discards it and logs `JevGuard skipped ·
209
+ interrupted|failed`.
171
210
 
172
211
  ## Safe auto-propose remediation
173
212
 
@@ -178,7 +217,7 @@ delivered entirely by the same server plugin.
178
217
 
179
218
  When `.jev/config.yaml` enables remediation (it is enabled by default) and a review
180
219
  contains any `FAIL`, the plugin, after presenting the review, sends one aggregate
181
- proposal request to a hidden `jevguard-proposer` subagent:
220
+ proposal request to an isolated child session:
182
221
 
183
222
  - The request aggregates every `FAIL` finding in the review — local `error` rules and
184
223
  the `SCOPE-CREEP` built-in — together with the turn's task and its **complete, safe,
@@ -188,28 +227,33 @@ proposal request to a hidden `jevguard-proposer` subagent:
188
227
  attributed file is blocked or the patch is oversized, the plugin records no proposal
189
228
  at all — even when a rule-scoped `FAIL` exists — because there is no complete safe
190
229
  evidence to send. It never falls back to a repository or global diff.
191
- - The request is sent in an isolated child session parented to the source session. The
192
- `jevguard-proposer` subagent has wildcard-deny permissions and wildcard-disabled
193
- tools, so it cannot call a tool, edit a file, or produce a patch. It returns a
194
- strategy and one manual apply instruction only.
195
- - `remediation.model` is optional. When set in `.jev/config.yaml`, it selects the
196
- proposer model; when it is absent, the proposer inherits the host's model.
197
- - A generic toast reports that the proposal is ready in the child session. It carries
198
- no rule, task, diff, finding, or credential.
230
+ - The request is sent in an isolated child session parented to the source session.
231
+ The child session is created with wildcard-deny permissions, so it cannot call a
232
+ tool, edit a file, or produce a patch. It returns a strategy and one manual apply
233
+ instruction only. No agent is registered for it.
234
+ - The child session always gets an explicit model: `remediation.model` from
235
+ `.jev/config.yaml` when set, otherwise the model of the source session. When neither
236
+ is known, no proposal is created and the plugin logs
237
+ `REMEDIATION_PROPOSAL_SKIPPED_NO_MODEL`.
238
+ - A proposal that does not finish within 120 seconds is interrupted and logged as
239
+ `REMEDIATION_PROPOSAL_TIMEOUT`.
240
+ - The server plugin has no toast or TUI channel on OpenCode `2.2.x`, so readiness is
241
+ reported through the structured log only. It carries no rule, task, diff, finding,
242
+ or credential.
199
243
 
200
244
  The plugin creates at most one proposal per evaluated turn, and the child session is
201
245
  excluded from review for the plugin lifetime, so a proposal can never recurse or
202
246
  trigger a second one. A host, model, or toast failure is contained and never changes
203
247
  the review. A contained proposal failure — an invalid model specifier, a child-session
204
- failure, or a prompt failure — shows a generic error toast and writes one structured
248
+ failure, a prompt failure, or a timeout — writes one structured
205
249
  `error` log entry carrying only a typed reason code, never any task, diff, finding,
206
250
  path, or credential.
207
251
 
208
252
  The proposer is a strategy step, not an apply step: it never edits code, and nothing
209
253
  is applied automatically. You read the proposal, copy its manual apply instruction
210
- into your normal coding agent, and apply it there. That apply is an ordinary completed
211
- assistant turn, so the server plugin reviews it normally on the next idle — exactly
212
- like any other turn.
254
+ into your normal coding agent, and apply it there. That apply is an ordinary
255
+ execution, so the server plugin reviews it normally when it succeeds — exactly like any
256
+ other turn.
213
257
 
214
258
  The proposal prompt treats the task, paths, diff, rules, and findings as untrusted
215
259
  data, and requires a separate explicit confirmation before proposing changes to tests,
@@ -219,8 +263,14 @@ or secret is logged.
219
263
  ## Install
220
264
 
221
265
  Installing `@pablozrrrr/jevguard` does **not** register it with OpenCode by itself.
222
- OpenCode only loads plugins listed in `plugin: [...]` in `opencode.json`, so register
223
- the plugin from the installed CLI:
266
+ OpenCode `2.2.x` only loads plugins listed in `plugins: [...]` in `opencode.json`.
267
+
268
+ > [!WARNING]
269
+ > The `jevguard install` command below still writes the OpenCode `1.x` `plugin` key.
270
+ > Until it is migrated, register the plugin on `2.2.x` with the manual `plugins`
271
+ > entry shown after it.
272
+
273
+ The installer is run from the installed CLI:
224
274
 
225
275
  ```sh
226
276
  # global config: ~/.config/opencode/opencode.json
@@ -230,10 +280,12 @@ jevguard install
230
280
  jevguard install --project
231
281
  ```
232
282
 
233
- The installer asks for confirmation, edits only the `plugin` array, and is
234
- idempotent. It only edits a `plugin` array of plain strings, so OpenCode's
235
- `[["pkg", { "options": {} }]]` tuple form is a known limitation: the installer leaves
236
- the file unchanged and prints the manual snippet instead. If `jevguard` is not on
283
+ The installer asks for confirmation, edits only the `plugins` array, and is
284
+ idempotent. It never writes the legacy `plugin` key, but an entry already there counts
285
+ as installed. It only edits a `plugins` array of package strings or
286
+ `{ "package": "..." }` objects; any other shape is left unchanged and the installer
287
+ prints the manual snippet instead. `jevguard doctor` also checks that
288
+ `opencode --version` is in the supported range `>=2.2.2 <2.3`. If `jevguard` is not on
237
289
  `PATH`, run it through `bunx`:
238
290
 
239
291
  ```sh
@@ -243,7 +295,7 @@ bunx --package @pablozrrrr/jevguard jevguard install
243
295
  The manual alternative is one entry in `opencode.json`:
244
296
 
245
297
  ```json
246
- { "plugin": ["@pablozrrrr/jevguard"] }
298
+ { "plugins": ["@pablozrrrr/jevguard"] }
247
299
  ```
248
300
 
249
301
  OpenCode resolves the package from the npm registry or its cache and loads it on the
@@ -258,9 +310,9 @@ after changing the plugin list.
258
310
  ### Build the local artifact
259
311
 
260
312
  The artifact ships the plugin as a **locally packed tarball** that bundles the
261
- private `@jevguard/core` and `@jevguard/opencode-adapter` workspace code, so a
262
- clean consumer installs one tarball and never resolves a workspace link or a
263
- private registry package. It also packages the `jevguard-rules` and `jev-init`
313
+ private `@jevguard/core`, `@jevguard/node-infra` and `@jevguard/opencode-adapter`
314
+ workspace code, so a clean consumer installs one tarball and never resolves a
315
+ workspace link or a private registry package. It also packages the `jevguard-rules` and `jev-init`
264
316
  skills and their private validators under `skills/<name>/`.
265
317
 
266
318
  Build the tarball from this repository:
@@ -282,12 +334,12 @@ does not vendor them and does not promise an offline install.
282
334
 
283
335
  ### Load the plugin
284
336
 
285
- OpenCode `1.18.32` resolves a **bare** `opencode.json` `plugin` entry from the npm
337
+ OpenCode `2.2.x` resolves a **bare** `opencode.json` `plugins` entry from the npm
286
338
  registry or its cache:
287
339
 
288
340
  ```json
289
341
  {
290
- "plugin": ["@pablozrrrr/jevguard"]
342
+ "plugins": ["@pablozrrrr/jevguard"]
291
343
  }
292
344
  ```
293
345
 
@@ -301,18 +353,36 @@ bun add /path/to/pablozrrrr-jevguard-<version>.tgz
301
353
 
302
354
  ```ts
303
355
  // .opencode/plugins/jevguard.ts
304
- export { JevGuardPlugin } from "@pablozrrrr/jevguard";
356
+ export { default } from "@pablozrrrr/jevguard";
305
357
  ```
306
358
 
307
359
  OpenCode loads `.opencode/plugins/` with its bundled Bun runtime. The shim runs as
308
360
  a local plugin module and resolves `@pablozrrrr/jevguard` from
309
- `.opencode/node_modules`. Use either the bare `plugin` entry or the local shim, not
361
+ `.opencode/node_modules`. Use either the bare `plugins` entry or the local shim, not
310
362
  both.
311
363
 
312
- Remediation is built into the same server plugin: the `config` hook registers the
313
- hidden `jevguard-proposer` subagent, so no second entrypoint or shim is needed. The
314
- server plugin reviews and reports turns, and — when remediation is enabled and a review
315
- fails — creates the proposal child session automatically.
364
+ The package's default export is the V2 plugin object (`{ id: "jevguard", setup }`).
365
+ Remediation is built into the same server plugin, so no second entrypoint or shim is
366
+ needed: it reviews and reports executions, and — when remediation is enabled and a
367
+ review fails — creates the proposal child session automatically. The bundled skills are
368
+ registered through the host skill editor (`skill.transform`).
369
+
370
+ ### Claude Code
371
+
372
+ Inside Claude Code:
373
+
374
+ ```text
375
+ /plugin marketplace add pablozr/JevGuard
376
+ /plugin install jevguard@jevguard
377
+ ```
378
+
379
+ The Claude Code plugin reviews each closed unit of work in a detached background
380
+ worker, shows the result in the session (status line, transcript line, and a toast on
381
+ `FAIL`) without sending it to the model, and records it in the same local history.
382
+ Remediation proposals are off by default and are enabled from your user config, never
383
+ from the repository. It needs `node` `>=22.13.0`, `npm`, and `git` on `PATH`. See the
384
+ [Claude Code guide](./docs/configuration.md#claude-code) for what is reviewed, the
385
+ in-session display, and remediation.
316
386
 
317
387
  ### Author rules with the bundled skill
318
388
 
@@ -361,11 +431,36 @@ jevguard login
361
431
 
362
432
  Known limitations:
363
433
 
364
- - Target host is OpenCode `1.18.32`. Exact `1.18.32` runtime smoke is still
365
- pending; a local `1.18.28` run worked.
434
+ - Target host is OpenCode `2.2.x` (minimum `2.2.2`). The plugin does not load on
435
+ `2.1.x` or `1.x`. A real-host smoke on `2.2.2` (2026-11-02) covered observe
436
+ and `remediate` (FAIL review, deny-all proposer, attempt 1/2, `RESOLVED`).
437
+ - OpenCode `2.2.2` does not install dependencies for a `file:` plugin spec. Use
438
+ the registry package; a local `file:` build needs its dependencies installed
439
+ next to it.
366
440
  - The plugin and CLI run on Bun, and the packed `jevguard` bin keeps a Bun
367
441
  shebang. Install and run the artifact with the Bun runtime.
368
442
 
443
+ ### OpenCode 2.2.x limitations
444
+
445
+ - **Minimum version `2.2.2`.** The plugin declares `engines.opencode` `>=2.2.2 <2.3`
446
+ and is pinned to the `2.2.x` plugin API.
447
+ - **Git-ignored files are out of scope.** The execution snapshot comes from the host's
448
+ working-tree diff, which leaves out files ignored by Git; a write the diff cannot
449
+ show makes the execution `UNAVAILABLE` (`INCOMPLETE_FILE_DIFF`) instead of reviewing
450
+ a partial patch.
451
+ - **Interrupted or failed executions are not reviewed.** Their writes stay on disk and
452
+ count as pre-existing changes for the next execution's snapshot, so they are not
453
+ attributed to it.
454
+ - **`opencode run --standalone`.** The review runs after the execution succeeds; a
455
+ standalone run can exit before it finishes. JevGuard reviews reliably in the TUI or
456
+ with `opencode serve` plus `opencode run --server`.
457
+ - **Concurrent executions.** When two sessions run at once, or an execution starts
458
+ while the previous one is still being finished, the review is `UNAVAILABLE`
459
+ (`CONCURRENT_SESSIONS`, `BOUNDARY_RACE`) instead of mixing changes. Nested child
460
+ sessions count as part of their parent execution.
461
+ - **No toast or TUI routing.** The server plugin reports through structured logs
462
+ written to the host's stderr capture.
463
+
369
464
  ## Connect Jev
370
465
 
371
466
  For local use, connect once with the installed command:
@@ -390,8 +485,8 @@ JevGuard FAIL
390
485
  pass 1 · warn 1 · fail 1 · skipped 0 · unavailable 0
391
486
  ```
392
487
 
393
- One toast per turn shows the aggregate outcome and the outcome counts; the
394
- structured log carries every rule's result, its raw violation probability or typed
488
+ The structured log (and, on hosts with a toast channel, one toast per turn) shows
489
+ the aggregate outcome and the outcome counts; the structured log carries every rule's result, its raw violation probability or typed
395
490
  reason, and its scoped paths. The counts include every entry, including the single
396
491
  synthetic entry a review-level failure produces.
397
492
 
@@ -427,6 +522,65 @@ The report prints aggregated counts, rule IDs, check IDs, and reason codes only
427
522
  never file paths, tasks, diffs, or credentials. A missing or empty history is a
428
523
  normal empty report, not an error.
429
524
 
525
+ ### Rule feedback
526
+
527
+ Tell JevGuard whether a `FAIL` was right. The answer is stored locally and only
528
+ feeds the calibration shown by `jevguard report`; it never changes a rule, a
529
+ threshold, or what the model returns.
530
+
531
+ ```sh
532
+ # unanswered rule FAILs, newest first, numbered
533
+ jevguard feedback
534
+
535
+ # answer one: right = a real violation, wrong = a false alarm
536
+ jevguard feedback 1 wrong
537
+ ```
538
+
539
+ Numbers stay fixed to the last listing. Built-in checks are not covered. See
540
+ [configuration](./docs/configuration.md)
541
+ for details.
542
+
543
+ ## Diagnose your setup
544
+
545
+ `jevguard doctor` checks your local setup without touching the network or changing
546
+ anything:
547
+
548
+ ```sh
549
+ jevguard doctor
550
+ jevguard doctor --json
551
+ ```
552
+
553
+ It reports `OK`, `WARN` or `FAIL` for the credential source, `.jev/rules.md`,
554
+ `.jev/config.yaml` and the OpenCode plugin registration, each with a hint when
555
+ something is wrong. It never prints the API key or any part of it — only whether the
556
+ key comes from the OS credential store or the `TYPESAFE_API_KEY` override. It exits
557
+ `0` unless a check fails (warnings are fine) and `1` when one does. The project root is
558
+ the first parent directory of the current directory that contains `.git`, or the
559
+ current directory when there is none. It does not check Claude Code installs yet.
560
+
561
+ ## Check rules on demand
562
+
563
+ `jevguard rules check` runs your repository rules against a diff you provide, without
564
+ waiting for an agent turn:
565
+
566
+ ```sh
567
+ git diff --cached | jevguard rules check --diff - --task "Add rate limiting to login"
568
+ jevguard rules check --diff change.diff --rule ARCH-001 --json
569
+ ```
570
+
571
+ It evaluates the repository rules over the diff with the same scope filtering,
572
+ evidence safety, slicing and gate thresholds as a review, but runs no built-in checks,
573
+ starts no remediation and writes nothing to the review history. The input must be
574
+ plain `git diff` output (or a plain `---`/`+++` unified diff) with `a/` and `b/`
575
+ prefixes; anything else is refused whole, never partly evaluated (see
576
+ [configuration](./docs/configuration.md#cli-diagnostics-and-on-demand-rule-checks)).
577
+ `--task` is optional; without it a neutral default task is sent. It prints each rule's outcome, probability, severity and
578
+ scoped paths, never the task or the diff. Exit codes: `0` completed with no `FAIL` and
579
+ no `UNAVAILABLE`; `1` at least one rule `FAIL`ed; `2` it could not check completely
580
+ (invalid arguments, an unreadable or unsupported diff, an unknown `--rule`, or an
581
+ `UNAVAILABLE` result). See [configuration](./docs/configuration.md#cli-diagnostics-and-on-demand-rule-checks)
582
+ for the full contract.
583
+
430
584
  ## Implemented behavior
431
585
 
432
586
  The current release implements the full local review path:
@@ -466,20 +620,20 @@ The current release implements the full local review path:
466
620
  attributed patch a built-in is `SKIPPED`; blocked or oversized evidence is
467
621
  `UNAVAILABLE`; a rule, policy-load, or config failure never suppresses the batch, and
468
622
  one built-in's answer never suppresses the other.
469
- - Reviews run in the background. The idle event resolves as soon as the serialized
470
- attribution step is scheduled, so policy reads, Jev calls, and presentation do not
471
- block the agent.
623
+ - Reviews run in the background. The `session.execution.succeeded` handler returns
624
+ as soon as the serialized attribution step is scheduled, so policy reads, Jev calls,
625
+ and presentation do not block the agent.
472
626
  - The local gate maps each rule to `PASS`, `WARN`, or `FAIL`; a rule with no
473
627
  applicable scope is `SKIPPED`, and a rule that cannot be safely evaluated is
474
628
  `UNAVAILABLE`.
475
- - One aggregate TUI toast and one structured log entry report the turn. The log
629
+ - One structured log entry reports the turn (the `2.2.x` server plugin has no toast
630
+ channel). The log
476
631
  carries every entry's outcome, raw probability, or reason, including the built-in
477
632
  results and the synthetic review-level entry when there is one. The fixed result
478
633
  order is rules in source order, then `SCOPE-CREEP`, then `COMPLEXITY`.
479
634
  - After presentation, when remediation is enabled and the review contains any `FAIL`,
480
- at most one aggregate proposal request is sent to the hidden `jevguard-proposer`
481
- subagent in an isolated child session parented to the source session, and a generic
482
- toast reports that the proposal is ready. The request carries every `FAIL` finding
635
+ at most one aggregate proposal request is sent to an isolated, deny-all child
636
+ session parented to the source session, with an explicit model. The request carries every `FAIL` finding
483
637
  (local `error` rules and the `SCOPE-CREEP` built-in), the task, and the complete,
484
638
  safe, full attributed patch; a blocked or oversized patch records no proposal. A
485
639
  notifier or host failure never affects the review, presentation, or later turns.
@@ -491,30 +645,25 @@ ordinary turn is reviewed normally.
491
645
 
492
646
  ## Roadmap
493
647
 
494
- The multi-rule, scope-creep, and complexity slices are implemented. Planned work
495
- beyond them:
648
+ Implemented so far: multi-rule reviews, the `SCOPE-CREEP` and `COMPLEXITY`
649
+ built-ins, the `jev-init` policy bootstrap, local review history with feedback and
650
+ calibration (`jevguard report`, `jevguard feedback`), on-demand checks
651
+ (`jevguard rules check`, `jevguard doctor`), and the Claude Code plugin. Planned work:
496
652
 
497
653
  ```text
498
- V0.3 Remaining built-in semantic check: test adequacy
499
- ↓
500
- V0.4 jev-init: evidence-based policy bootstrap
501
- ↓
502
- V0.5 On-demand evidence and explanations
503
- ↓
504
- V0.6 Opt-in, bounded auto-remediation
505
- ↓
506
- V0.7 Observe / enforce / remediate modes
507
- ↓
508
- V0.8 Rule packs
509
- ↓
510
- V0.9 Local feedback and calibration
511
- ↓
512
- V1 Claude Code and Codex adapters
654
+ V0.3 Remaining built-in semantic check: test adequacy planned
655
+ V0.4 jev-init: evidence-based policy bootstrap done
656
+ V0.5 On-demand evidence and explanations partial (rules check)
657
+ V0.6 Opt-in, bounded auto-remediation planned
658
+ V0.7 Observe / enforce / remediate modes planned
659
+ V0.8 Rule packs planned
660
+ V0.9 Local feedback and calibration done
661
+ V1 Claude Code and Codex adapters Claude Code done, Codex planned
513
662
  ```
514
663
 
515
664
  The auto-propose slice is implemented: after a review with a `FAIL`, an enabled
516
- configuration asks the hidden `jevguard-proposer` subagent for a strategy in an
517
- isolated child session, and never applies a change. The `V0.6` entry remains the
665
+ configuration asks for a strategy in an isolated, deny-all child session, and never
666
+ applies a change. The `V0.6` entry remains the
518
667
  future, unattended corrective loop; the proposer is a bounded, strategy-only step, not
519
668
  that loop.
520
669
 
@@ -527,17 +676,24 @@ CI and pull-request policy review come after V1, using the same versioned rules.
527
676
 
528
677
  ## Architecture
529
678
 
530
- JevGuard is a pnpm TypeScript monorepo. The core has no dependency on OpenCode or
531
- its runtime, which keeps the evaluation model portable to future adapters.
679
+ JevGuard is a pnpm TypeScript monorepo. The core has no dependency on OpenCode,
680
+ Claude Code, or their runtimes, which keeps the evaluation model portable across
681
+ host adapters.
532
682
 
533
683
  ```text
534
684
  packages/
535
685
  ├── core/ domain, policy, evaluation, gate
686
+ ├── claude-code-adapter/ Claude Code tool-attributed units, hook and review worker
687
+ ├── claude-code-plugin/ Claude Code plugin composition and artifact
688
+ ├── node-infra/ shared Node infra: credentials, Jev transport, policy, history
536
689
  ├── opencode-adapter/ OpenCode attribution and presentation
537
690
  ├── plugin/ OpenCode composition root and CLI
538
691
  └── testkit/ fixtures and contract helpers
539
692
 
540
- plugin → opencode-adapter → core
693
+ plugin → opencode-adapter → node-infra → core
694
+ plugin ────────────────────→ node-infra
695
+ claude-code-plugin → claude-code-adapter → node-infra → core
696
+ testkit ──────────────────────────────→ core
541
697
  ```
542
698
 
543
699
  ## Status
@@ -548,18 +704,23 @@ loads in OpenCode, attributes one completed turn, parses every rule block in
548
704
  the `SCOPE-CREEP`
549
705
  and `COMPLEXITY` built-ins over the complete attributed patch behind one shared
550
706
  concurrency limit, applies the local gate to each, and presents one aggregate result
551
- as a transient TUI toast and a structured log entry.
707
+ as a structured log entry.
552
708
 
553
709
  The local, private tarball (`pnpm artifact:build`, `pnpm artifact:pack`) packages
554
710
  that slice so a clean consumer can install it without workspace links.
555
711
 
556
- OpenCode sees only transient toasts, structured logs, and — when remediation is
557
- enabled and a review has a `FAIL` — one proposal child session and a generic toast.
712
+ OpenCode sees only structured logs and — when remediation is enabled and a review
713
+ has a `FAIL` — one proposal child session.
558
714
  The review does not inject anything into the agent context, prompt the source session,
559
715
  add session messages, or block a task. The proposal is a separate, configurable,
560
716
  strategy-only workflow delivered by the server plugin; it never edits code and never
561
- applies a change. Real-host validation against exact OpenCode `1.18.32` is still
562
- pending.
717
+ applies a change. A real-host smoke on OpenCode `2.2.2` passed; see
718
+ [OpenCode 2.2.x limitations](#opencode-22x-limitations).
719
+
720
+ The Claude Code plugin reuses the same core, policy files, gate, and local history. It
721
+ reviews closed units of work in a detached worker and shows results in the session
722
+ without sending them to the model; see the
723
+ [Claude Code guide](./docs/configuration.md#claude-code).
563
724
 
564
725
  ## Development
565
726