gentle-pi 2.1.2 → 2.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.
Files changed (228) hide show
  1. package/README.md +108 -79
  2. package/assets/agents/gentle-ai-worker.md +7 -3
  3. package/assets/agents/jd-fix-agent.md +1 -1
  4. package/assets/agents/jd-judge-a.md +3 -1
  5. package/assets/agents/jd-judge-b.md +3 -1
  6. package/assets/agents/review-readability.md +4 -3
  7. package/assets/agents/review-reliability.md +4 -3
  8. package/assets/agents/review-resilience.md +4 -3
  9. package/assets/agents/review-risk.md +4 -3
  10. package/assets/agents/sdd-apply.md +11 -4
  11. package/assets/agents/sdd-archive.md +6 -1
  12. package/assets/agents/sdd-design.md +6 -1
  13. package/assets/agents/sdd-explore.md +6 -2
  14. package/assets/agents/sdd-init.md +10 -2
  15. package/assets/agents/sdd-onboard.md +6 -1
  16. package/assets/agents/sdd-proposal.md +8 -1
  17. package/assets/agents/sdd-research.md +54 -0
  18. package/assets/agents/sdd-spec.md +6 -1
  19. package/assets/agents/sdd-status.md +10 -5
  20. package/assets/agents/sdd-sync.md +6 -1
  21. package/assets/agents/sdd-tasks.md +8 -4
  22. package/assets/agents/sdd-verify.md +27 -2
  23. package/assets/chains/4r-review.chain.md +2 -0
  24. package/assets/chains/sdd-full.chain.md +2 -2
  25. package/assets/chains/sdd-plan.chain.md +1 -1
  26. package/assets/chains/sdd-verify.chain.md +2 -2
  27. package/assets/orchestrator-delegation.md +145 -160
  28. package/assets/orchestrator-memory.md +2 -0
  29. package/assets/orchestrator.md +25 -48
  30. package/assets/sdd-orchestrator-workflow.md +163 -25
  31. package/assets/support/sdd-status-contract.md +24 -6
  32. package/contracts/review-integration/v1/fixtures/consent.fixture.json +3 -3
  33. package/contracts/review-integration/v1/fixtures/start-v2.fixture.json +19 -28
  34. package/contracts/review-integration/v1/fixtures/start.fixture.json +1 -10
  35. package/contracts/review-integration/v1/fixtures/status-v2.fixture.json +12 -21
  36. package/contracts/review-integration/v1/schemas/correction-plan-request.schema.json +49 -0
  37. package/contracts/review-integration/v1/schemas/operation.schema.json +76 -0
  38. package/contracts/review-integration/v1/schemas/repair.schema.json +39 -0
  39. package/contracts/review-integration/v1/schemas/status-v2.schema.json +4 -2
  40. package/contracts/review-integration/v1/schemas/status.schema.json +4 -2
  41. package/contracts/review-integration/v1/schemas/transition-execution.schema.json +42 -0
  42. package/contracts/review-integration/v2/fixtures/consent.fixture.json +1 -1
  43. package/contracts/review-integration/v2/fixtures/start.fixture.json +1 -10
  44. package/contracts/review-integration/v2/fixtures/status.fixture.json +1 -10
  45. package/contracts/review-integration/v2/schemas/failure.schema.json +5 -1
  46. package/contracts/review-integration/v2/schemas/last-event-closure.schema.json +66 -0
  47. package/contracts/review-integration/v2/schemas/opencode-provider-role.schema.json +14 -0
  48. package/contracts/review-integration/v2/schemas/operation.schema.json +6 -1
  49. package/contracts/review-integration/v2/schemas/repair.schema.json +4 -2
  50. package/contracts/review-integration/v2/schemas/start.schema.json +5 -2
  51. package/contracts/review-integration/v2/schemas/status.schema.json +4 -2
  52. package/contracts/review-provider-contract-mirror/provider-contract.lock.json +30 -0
  53. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/README.md +12 -0
  54. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/manifest.json +65 -0
  55. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/lens.schema.json +16 -0
  56. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/refuter.schema.json +1 -0
  57. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/targeted-validator.schema.json +1 -0
  58. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/lens.json +1 -0
  59. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/refuter.json +1 -0
  60. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/targeted-validator.json +1 -0
  61. package/contracts/review-provider-contract-mirror/v1.1.0/generated/provider-capabilities.baseline.json +15 -0
  62. package/contracts/review-provider-contract-mirror/v1.1.0/generated/provider-roles.baseline.json +42 -0
  63. package/docs/native-authority-architecture.md +14 -16
  64. package/docs/review-integration.md +27 -353
  65. package/extensions/ask-user-choice.ts +151 -0
  66. package/extensions/gentle-ai.ts +2710 -3211
  67. package/extensions/quiet-tools.ts +515 -32
  68. package/extensions/sdd-init.ts +21 -12
  69. package/extensions/skill-registry.ts +10 -2
  70. package/extensions/startup-banner.ts +10 -4
  71. package/lib/gentle-ai-binary.ts +173 -2
  72. package/lib/gentle-ai-renderer.ts +70 -0
  73. package/lib/model-routing-authority.ts +133 -0
  74. package/lib/native-review-cli.ts +676 -781
  75. package/lib/opaque-pi-reviewer-adapter.ts +284 -0
  76. package/lib/provider-contract-bundle.ts +704 -0
  77. package/lib/review-candidate-view.ts +836 -118
  78. package/lib/review-compact-contract.ts +59 -248
  79. package/lib/review-host-relay.ts +578 -0
  80. package/lib/review-integration-v2.ts +1254 -221
  81. package/lib/review-last-event-controller.ts +35 -0
  82. package/lib/review-relay-contract.ts +16 -0
  83. package/lib/sdd-preflight.ts +230 -67
  84. package/lib/sdd-status.ts +66 -111
  85. package/lib/terminal-theme.ts +1 -1
  86. package/package.json +83 -79
  87. package/runtime/gentle-ai-binary.mjs +174 -3
  88. package/runtime/native-review-cli.mjs +610 -715
  89. package/runtime/review-integration-v2.mjs +1223 -190
  90. package/runtime/review-relay-contract.mjs +17 -0
  91. package/scripts/{build-git-commit-transaction-runner.mjs → build-runtime-modules.mjs} +5 -5
  92. package/scripts/check-provider-contract.mjs +138 -0
  93. package/scripts/gentle-ai-installer.mjs +85 -22
  94. package/scripts/maintainer/provider-relay-matrix.mjs +403 -0
  95. package/scripts/mirror-provider-contract.mjs +143 -0
  96. package/scripts/test-packed-runner.mjs +20 -9
  97. package/scripts/verify-package-files.mjs +119 -43
  98. package/skills/_shared/review-ledger-contract.md +11 -19
  99. package/skills/chained-pr/SKILL.md +3 -0
  100. package/skills/cognitive-doc-design/SKILL.md +1 -1
  101. package/skills/comment-writer/SKILL.md +1 -1
  102. package/skills/gentle-ai/SKILL.md +7 -74
  103. package/skills/issue-creation/SKILL.md +94 -168
  104. package/skills/judgment-day/SKILL.md +9 -5
  105. package/skills/judgment-day/references/prompts-and-formats.md +2 -0
  106. package/skills/rdd-defect-workflow/SKILL.md +54 -0
  107. package/skills/release/SKILL.md +3 -3
  108. package/skills/skill-registry/SKILL.md +1 -1
  109. package/skills/work-unit-commits/SKILL.md +3 -1
  110. package/tests/artifact-language.test.ts +24 -11
  111. package/tests/ask-user-choice.test.ts +264 -0
  112. package/tests/background-subagents.test.ts +771 -0
  113. package/tests/codegraph-tools.test.ts +3 -3
  114. package/tests/crosslane/cross-lane.mjs +16 -0
  115. package/tests/delegated-key-learnings-contract.test.ts +240 -0
  116. package/tests/devbinary/native-review-parity.devtest.ts +167 -250
  117. package/tests/devbinary/pi-host-relay.devtest.ts +867 -0
  118. package/tests/fixtures/devbinary/capabilities-v2.1.derived.json +331 -0
  119. package/tests/fixtures/devbinary/capabilities-v2.2.captured.json +340 -0
  120. package/tests/fixtures/devbinary/consent-v3.captured.json +37 -0
  121. package/tests/fixtures/devbinary/failure-v2-capture-evidence.captured.json +16 -0
  122. package/tests/fixtures/devbinary/last-event-capture-correction-plan.captured.json +10 -0
  123. package/tests/fixtures/devbinary/last-event-capture-refuter-approved.captured.json +20 -0
  124. package/tests/fixtures/devbinary/last-event-capture-refuter-correction-required.captured.json +26 -0
  125. package/tests/fixtures/devbinary/last-event-capture-result-approved.captured.json +8 -0
  126. package/tests/fixtures/devbinary/last-event-capture-result-correction-required.captured.json +26 -0
  127. package/tests/fixtures/devbinary/last-event-capture-validation-approved.captured.json +8 -0
  128. package/tests/fixtures/devbinary/last-event-closure.provenance.md +13 -0
  129. package/tests/fixtures/devbinary/result-artifact-v2-path.captured.json +12 -0
  130. package/tests/fixtures/devbinary/result-artifact-v2.captured.json +12 -0
  131. package/tests/fixtures/devbinary/review-acknowledged-v1.captured.json +9 -0
  132. package/tests/fixtures/devbinary/review-acknowledged.provenance.md +31 -0
  133. package/tests/fixtures/devbinary/start-v3-consent-declined.captured.json +19 -0
  134. package/tests/fixtures/devbinary/start-v3-consent-granted.captured.json +109 -0
  135. package/tests/fixtures/devbinary/start-v3-zero-lens-closed.captured.json +21 -0
  136. package/tests/fixtures/devbinary/status-v5-capture-result-submission.captured.json +184 -0
  137. package/tests/fixtures/devbinary/status-v5-repository-context.captured.json +138 -0
  138. package/tests/fixtures/devbinary/status-v5.captured.json +88 -0
  139. package/tests/fixtures/native-review-cli/v2.5.0-rc.1/PROVENANCE.txt +15 -0
  140. package/tests/fixtures/provider-contract-bundle/v1.1.0/README.md +12 -0
  141. package/tests/fixtures/provider-contract-bundle/v1.1.0/manifest.json +65 -0
  142. package/tests/fixtures/provider-contract-bundle/v1.1.0/schemas/lens.schema.json +16 -0
  143. package/tests/fixtures/provider-contract-bundle/v1.1.0/schemas/refuter.schema.json +1 -0
  144. package/tests/fixtures/provider-contract-bundle/v1.1.0/schemas/targeted-validator.schema.json +1 -0
  145. package/tests/fixtures/provider-contract-bundle/v1.1.0/vectors/lens.json +1 -0
  146. package/tests/fixtures/provider-contract-bundle/v1.1.0/vectors/refuter.json +1 -0
  147. package/tests/fixtures/provider-contract-bundle/v1.1.0/vectors/targeted-validator.json +1 -0
  148. package/tests/gentle-ai-binary.test.ts +83 -13
  149. package/tests/gentle-ai-dev-binary-surfacing.test.ts +195 -0
  150. package/tests/gentle-ai-dev-binary.test.ts +159 -0
  151. package/tests/gentle-ai-installer.test.ts +138 -48
  152. package/tests/gentle-ai.test.ts +820 -131
  153. package/tests/gentle-theme.test.ts +133 -0
  154. package/tests/maintainer/provider-relay.maintest.ts +601 -0
  155. package/tests/model-routing-authority.test.ts +257 -0
  156. package/tests/native-review-capability-contract.test.ts +75 -2
  157. package/tests/native-review-cli.test.ts +588 -908
  158. package/tests/native-review-consent.test.ts +283 -38
  159. package/tests/native-review-parity-runtime.test.ts +108 -350
  160. package/tests/native-review-parity.test.ts +684 -732
  161. package/tests/native-sdd-attempt-authority.test.ts +235 -0
  162. package/tests/opaque-pi-reviewer-adapter.test.ts +266 -0
  163. package/tests/orchestrator-budget.test.ts +158 -89
  164. package/tests/orchestrator-rdd-ownership.test.ts +103 -0
  165. package/tests/package-manifest.test.ts +128 -100
  166. package/tests/provider-contract-bundle.test.ts +385 -0
  167. package/tests/provider-contract-mirror.test.ts +206 -0
  168. package/tests/provider-defect-handoff.test.ts +252 -0
  169. package/tests/quiet-tool-rendering.test.ts +1055 -28
  170. package/tests/review-actor-tool-deny.test.ts +12 -13
  171. package/tests/review-authority-recovery-docs.test.ts +1 -2
  172. package/tests/review-candidate-view.test.ts +898 -12
  173. package/tests/review-compact-contract.test.ts +29 -122
  174. package/tests/review-controller-lock-status.test.ts +2 -2
  175. package/tests/review-controller-native-recovery.test.ts +366 -857
  176. package/tests/review-controller-native-routing.test.ts +1253 -4199
  177. package/tests/review-controller-retired-ops.test.ts +1 -1
  178. package/tests/review-controller-workspace-root.test.ts +236 -70
  179. package/tests/review-controller.test.ts +26 -816
  180. package/tests/review-corrected-finalize-binding.test.ts +134 -0
  181. package/tests/review-dispatch-hydration-gap.test.ts +145 -0
  182. package/tests/review-gate.test.ts +0 -45
  183. package/tests/review-host-relay-restart-parity.test.ts +360 -0
  184. package/tests/review-host-relay-routing.test.ts +352 -0
  185. package/tests/review-host-relay.test.ts +754 -0
  186. package/tests/review-integration-v2-forward.test.ts +654 -0
  187. package/tests/review-integration-v2.test.ts +317 -129
  188. package/tests/review-last-event-closure.test.ts +408 -0
  189. package/tests/review-ledger-contract.test.ts +106 -60
  190. package/tests/review-recovered-lineage-routing.test.ts +199 -0
  191. package/tests/review-relay-transport-agent.test.ts +322 -0
  192. package/tests/review-snapshot.test.ts +3 -2
  193. package/tests/runtime-harness.mjs +573 -180
  194. package/tests/sdd-agent-tools.test.ts +53 -32
  195. package/tests/sdd-preflight.test.ts +81 -15
  196. package/tests/sdd-status.test.ts +109 -110
  197. package/tests/skill-collision-prefixes.test.ts +6 -8
  198. package/tests/skill-registry.test.ts +50 -1
  199. package/tests/verify-package-files.test.ts +62 -0
  200. package/tests/writer-edit-surface-scope.test.ts +230 -0
  201. package/themes/Gentleman-Cute.json +94 -0
  202. package/themes/Gentleman-Sexy.json +92 -0
  203. package/assets/agents/review-refuter.md +0 -40
  204. package/assets/agents/review-validator.md +0 -23
  205. package/lib/git-commit-transaction.ts +0 -801
  206. package/lib/native-review-remediation.ts +0 -49
  207. package/lib/review-compact.ts +0 -947
  208. package/lib/review-refuter-adapter.ts +0 -129
  209. package/lib/review-runtime-contract.ts +0 -68
  210. package/prompts/gcl.md +0 -54
  211. package/prompts/gis.md +0 -25
  212. package/prompts/gpr.md +0 -41
  213. package/prompts/gwr.md +0 -31
  214. package/runtime/git-commit-transaction.mjs +0 -802
  215. package/scripts/run-git-commit-transaction.mjs +0 -35
  216. package/tests/fixtures/native-review-cli/v2.1.2/bind-sdd.json +0 -25
  217. package/tests/fixtures/native-review-cli/v2.1.2/finalize.json +0 -8
  218. package/tests/fixtures/native-review-cli/v2.1.2/sdd-status-engram.json +0 -139
  219. package/tests/fixtures/native-review-cli/v2.1.2/sdd-status.json +0 -200
  220. package/tests/fixtures/native-review-cli/v2.1.2/start.json +0 -12
  221. package/tests/fixtures/native-review-cli/v2.1.2/validate-allow.json +0 -24
  222. package/tests/fixtures/native-review-cli/v2.1.2/validate-deny-empty-context.json +0 -20
  223. package/tests/fixtures/native-review-cli/v2.1.2/validate-deny.json +0 -28
  224. package/tests/fixtures/native-review-cli/v2.1.3/sdd-status-engram.json +0 -139
  225. package/tests/fixtures/native-review-cli/v2.1.3/sdd-status.json +0 -200
  226. package/tests/git-commit-transaction.test.ts +0 -302
  227. package/tests/review-compact.test.ts +0 -243
  228. package/tests/review-refuter-adapter.test.ts +0 -89
@@ -0,0 +1,138 @@
1
+ {
2
+ "schema": "gentle-ai.review-integration.status/v5",
3
+ "contract": "gentle-ai.review-integration/v2",
4
+ "operation": "review.status",
5
+ "applicability": "current_target",
6
+ "authority": {
7
+ "version": "compact-v2",
8
+ "lineage_id": "review-bbfbf9af2dc27936",
9
+ "state": "reviewing",
10
+ "generation": 1,
11
+ "revision": "sha256:b330774b56c764047e6041de2b9071b16a772abf7cdc311c2f77cb4ecaa3a707"
12
+ },
13
+ "receipt": {
14
+ "status": "expected_missing"
15
+ },
16
+ "action": "finalize",
17
+ "replayability": "not_replayable",
18
+ "frozen": {
19
+ "tier": "medium",
20
+ "original_changed_lines": 1,
21
+ "correction_budget": 1
22
+ },
23
+ "target_identity": "sha256:bbfbf9af2dc27936d5fbc0c30579d5122d65bf4ccc65d9a00cde816f3aa6d3ab",
24
+ "projection": {
25
+ "schema": "gentle-ai.review-integration.projection/v1",
26
+ "kind": "current-changes",
27
+ "projection": "workspace",
28
+ "base_tree": "7bee507cb7f5aa4dce34e6962366eeea27935c74",
29
+ "initial_review_tree": "a044376c6cfb84e30c676ff7307e92bcfef5b6ec",
30
+ "current_candidate_tree": "a044376c6cfb84e30c676ff7307e92bcfef5b6ec",
31
+ "paths_digest": "sha256:4d916b1a185d946866be1c2f945425ea650ea045dec13bb0ec972744f0f9bd61",
32
+ "paths": [
33
+ "file.txt"
34
+ ],
35
+ "intended_untracked": [],
36
+ "intended_untracked_proof": "sha256:b97229718d4c7fe50a8892eb474ae5aa6491697bccb400e3e31dbaca4894d2f3",
37
+ "initial_snapshot_identity": "sha256:bbfbf9af2dc27936d5fbc0c30579d5122d65bf4ccc65d9a00cde816f3aa6d3ab",
38
+ "current_snapshot_identity": "sha256:bbfbf9af2dc27936d5fbc0c30579d5122d65bf4ccc65d9a00cde816f3aa6d3ab"
39
+ },
40
+ "repair": {
41
+ "schema": "gentle-ai.review-authority-repair-assessment/v1",
42
+ "status": "unsupported",
43
+ "counts": {
44
+ "lineages": 0,
45
+ "compact_lineages": 0,
46
+ "legacy_lineages": 0,
47
+ "events": 0,
48
+ "bytes": 0,
49
+ "eligible_candidates": 0,
50
+ "unsupported_lineages": 0,
51
+ "conflicts": 0
52
+ },
53
+ "supported_operations": [
54
+ "review/complete-fix",
55
+ "review/validate-fix"
56
+ ],
57
+ "authorization_schema": "gentle-ai.review-repair-authorization/v1"
58
+ },
59
+ "candidates": [],
60
+ "forecast": {
61
+ "horizon": "partial",
62
+ "steps": [
63
+ {
64
+ "step": 1,
65
+ "kind": "execute",
66
+ "reason_code": "captured_results_ready",
67
+ "description": "Captured reviewer results are complete and ready for finalization"
68
+ }
69
+ ]
70
+ },
71
+ "next_transition": {
72
+ "kind": "execute",
73
+ "reason_code": "captured_results_ready",
74
+ "execute": {
75
+ "operation": "review.finalize",
76
+ "command": "gentle-ai review finalize --lineage=review-bbfbf9af2dc27936 --captured-results=true --contract=gentle-ai.review-integration/v2 --agent=claude-code",
77
+ "arguments": [
78
+ {
79
+ "name": "lineage",
80
+ "value": "review-bbfbf9af2dc27936",
81
+ "token": "--lineage=review-bbfbf9af2dc27936"
82
+ },
83
+ {
84
+ "name": "captured_results",
85
+ "value": "true",
86
+ "token": "--captured-results=true"
87
+ },
88
+ {
89
+ "name": "contract",
90
+ "value": "gentle-ai.review-integration/v2",
91
+ "token": "--contract=gentle-ai.review-integration/v2"
92
+ },
93
+ {
94
+ "name": "agent",
95
+ "value": "claude-code",
96
+ "token": "--agent=claude-code"
97
+ }
98
+ ],
99
+ "preconditions": [
100
+ {
101
+ "name": "state",
102
+ "value": "reviewing"
103
+ },
104
+ {
105
+ "name": "captured_artifacts",
106
+ "value": "complete"
107
+ }
108
+ ],
109
+ "binding": {
110
+ "lineage_id": "review-bbfbf9af2dc27936",
111
+ "revision": "sha256:b330774b56c764047e6041de2b9071b16a772abf7cdc311c2f77cb4ecaa3a707",
112
+ "target_identity": "sha256:bbfbf9af2dc27936d5fbc0c30579d5122d65bf4ccc65d9a00cde816f3aa6d3ab",
113
+ "repository_context": "rctx1_7da80fda377da87da8aae62204c531e697bd6a4a6bbd5de21ddd3861150fb725"
114
+ },
115
+ "artifacts": [
116
+ {
117
+ "schema": "gentle-ai.review-result-artifact/v2",
118
+ "capability": "review.native_result_artifact",
119
+ "sha256": "sha256:02a403472b0bb0c7ad5dddd1010b006af257f516e425795996f276d423d33c9d",
120
+ "lineage_id": "review-bbfbf9af2dc27936",
121
+ "target_identity": "sha256:bbfbf9af2dc27936d5fbc0c30579d5122d65bf4ccc65d9a00cde816f3aa6d3ab",
122
+ "lens": "review-reliability",
123
+ "selected_order": 0,
124
+ "subject_hash": "sha256:620703b2e6f074e031712f501eb9fe460bb17bd0cbbd70db10be5dc4fa2dfead",
125
+ "admission_decision": "completed"
126
+ }
127
+ ]
128
+ }
129
+ },
130
+ "repository_context": {
131
+ "capability": "review.opaque_repository_context",
132
+ "handle": "rctx1_7da80fda377da87da8aae62204c531e697bd6a4a6bbd5de21ddd3861150fb725",
133
+ "revision": "sha256:b330774b56c764047e6041de2b9071b16a772abf7cdc311c2f77cb4ecaa3a707",
134
+ "target_identity": "sha256:bbfbf9af2dc27936d5fbc0c30579d5122d65bf4ccc65d9a00cde816f3aa6d3ab",
135
+ "event_id": "sha256:5d2588ff1422f4568588986a2e2872bae60f0fef4131df81a6e3bdad9f8fa76a",
136
+ "outcome": "applied"
137
+ }
138
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "schema": "gentle-ai.review-integration.status/v5",
3
+ "contract": "gentle-ai.review-integration/v2",
4
+ "operation": "review.status",
5
+ "applicability": "unrelated",
6
+ "receipt": {
7
+ "status": "not_applicable"
8
+ },
9
+ "action": "start",
10
+ "replayability": "not_replayable",
11
+ "target_identity": "sha256:50d13aa33f913bbf99df6ad5b94ac1db2aba969445ffc08aadffd8b42b79f1c4",
12
+ "projection": {
13
+ "schema": "gentle-ai.review-integration.projection/v1",
14
+ "kind": "current-changes",
15
+ "projection": "workspace",
16
+ "base_tree": "619289f137abd616d94899f2c9b6726de091ac92",
17
+ "initial_review_tree": "619289f137abd616d94899f2c9b6726de091ac92",
18
+ "current_candidate_tree": "619289f137abd616d94899f2c9b6726de091ac92",
19
+ "paths_digest": "sha256:2286a180488f90f2e97062d500a629bc747716d55a34c2861a8309e1b02589a1",
20
+ "paths": [],
21
+ "intended_untracked": [],
22
+ "intended_untracked_proof": "sha256:b97229718d4c7fe50a8892eb474ae5aa6491697bccb400e3e31dbaca4894d2f3",
23
+ "initial_snapshot_identity": "sha256:50d13aa33f913bbf99df6ad5b94ac1db2aba969445ffc08aadffd8b42b79f1c4",
24
+ "current_snapshot_identity": "sha256:50d13aa33f913bbf99df6ad5b94ac1db2aba969445ffc08aadffd8b42b79f1c4"
25
+ },
26
+ "repair": {
27
+ "schema": "gentle-ai.review-authority-repair-assessment/v1",
28
+ "status": "unsupported",
29
+ "counts": {
30
+ "lineages": 0,
31
+ "compact_lineages": 0,
32
+ "legacy_lineages": 0,
33
+ "events": 0,
34
+ "bytes": 0,
35
+ "eligible_candidates": 0,
36
+ "unsupported_lineages": 0,
37
+ "conflicts": 0
38
+ },
39
+ "supported_operations": [
40
+ "review/complete-fix",
41
+ "review/validate-fix"
42
+ ],
43
+ "authorization_schema": "gentle-ai.review-repair-authorization/v1"
44
+ },
45
+ "candidates": [],
46
+ "forecast": {
47
+ "horizon": "partial",
48
+ "steps": [
49
+ {
50
+ "step": 1,
51
+ "kind": "collect",
52
+ "reason_code": "empty_candidate_base_ref_required",
53
+ "description": "empty candidate base ref required"
54
+ }
55
+ ]
56
+ },
57
+ "next_transition": {
58
+ "kind": "collect",
59
+ "reason_code": "empty_candidate_base_ref_required",
60
+ "collect": {
61
+ "inputs": [
62
+ {
63
+ "name": "base_ref",
64
+ "schema": "gentle-ai.review-base-ref-selection/v1",
65
+ "capture_operation": "external.select_base_ref",
66
+ "arguments": [
67
+ {
68
+ "name": "target_identity",
69
+ "value": "sha256:50d13aa33f913bbf99df6ad5b94ac1db2aba969445ffc08aadffd8b42b79f1c4"
70
+ },
71
+ {
72
+ "name": "projection",
73
+ "value": "workspace"
74
+ },
75
+ {
76
+ "name": "base_tree",
77
+ "value": "619289f137abd616d94899f2c9b6726de091ac92"
78
+ },
79
+ {
80
+ "name": "candidate_tree",
81
+ "value": "619289f137abd616d94899f2c9b6726de091ac92"
82
+ }
83
+ ]
84
+ }
85
+ ]
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,15 @@
1
+ Captured from a real gentle-ai binary, not hand-authored.
2
+
3
+ binary: gentle-ai 2.5.0-rc.1.0.20260827194839-f654764e231f (published prerelease channel)
4
+ date: 2026-08-28
5
+ command: gentle-ai sdd-status agent-builder --cwd <repo> --json --instructions
6
+ repo: a gentle-ai checkout with an OpenSpec-backed change present
7
+
8
+ Why this fixture exists: gentle-ai commit 3c4c7fb6 (2026-08-24, "refactor(sdd)!:
9
+ replace status v1 with clean v2") moved SchemaVersion from 1 to 2. gentle-pi had
10
+ no v2 decoder, so lib/native-review-cli.ts rejected every current status with
11
+ IDENTITY_MISMATCH on `body.schemaVersion !== 1`.
12
+
13
+ The v2 object shape is key-compatible with the v1 decoder's exactObject list:
14
+ 17 required keys plus the optional phaseInstructions. Only the version value and
15
+ the widened artifactStore domain (which gains "hybrid") differ.
@@ -0,0 +1,12 @@
1
+ # Gentle AI review provider contract
2
+
3
+ This data-only bundle describes the provider result contracts admitted by Gentle AI.
4
+
5
+ ## Activation
6
+
7
+ 1. Verify the signed release checksum manifest before using this archive.
8
+ 2. Verify every listed file hash and the transport capability before activation.
9
+ 3. Confirm your runtime identity appears in the manifest's registered runtimes before trusting the layout.
10
+ 4. Pass the Go-materialized opaque prompt to the provider and return only raw output or an error.
11
+
12
+ Go remains the admission authority for prompts, results, receipts, and delivery gates.
@@ -0,0 +1,65 @@
1
+ {
2
+ "schema": "gentle-ai.review-provider-contract-bundle/v1",
3
+ "contract_semver": "1.1.0",
4
+ "transport_capability": "gentle-ai.provider-transport/v1",
5
+ "runtimes": [
6
+ "claude-code",
7
+ "codex",
8
+ "opencode",
9
+ "pi"
10
+ ],
11
+ "readme": {
12
+ "path": "README.md",
13
+ "sha256": "d14647c8753bd85e18b8a593bef9dfcb4c9d8ea01e32ecd36847dc4304027b1d"
14
+ },
15
+ "roles": [
16
+ {
17
+ "id": "lens",
18
+ "request_schema_id": "gentle-ai.review-lens-context/v1",
19
+ "result_schema_id": "https://gentle-ai.dev/schema/review/reviewer/v1",
20
+ "required_capabilities": [
21
+ "gentle-ai.provider-transport/v1"
22
+ ],
23
+ "schema": {
24
+ "path": "schemas/lens.schema.json",
25
+ "sha256": "ffef79cfb763333282285ff5c795a32b5a88d840b4a8d125ce012188b04cffe1"
26
+ },
27
+ "vector": {
28
+ "path": "vectors/lens.json",
29
+ "sha256": "7ef0b08404645eeb5dba92aba5f8e4780667b6ec775f43ed8547ff9f2a7148c8"
30
+ }
31
+ },
32
+ {
33
+ "id": "refuter",
34
+ "request_schema_id": "gentle-ai.review-provider-refuter-request/v1",
35
+ "result_schema_id": "https://gentle-ai.dev/schema/review/refuter/v1",
36
+ "required_capabilities": [
37
+ "gentle-ai.provider-transport/v1"
38
+ ],
39
+ "schema": {
40
+ "path": "schemas/refuter.schema.json",
41
+ "sha256": "36f8267c6c3f04600b8f1cb77df70d90858611af822cc81922efd6b3502fb646"
42
+ },
43
+ "vector": {
44
+ "path": "vectors/refuter.json",
45
+ "sha256": "f42d71906e49c4191660b2da7e70f01f1778b23d32089005bd2d7ae9cbb73039"
46
+ }
47
+ },
48
+ {
49
+ "id": "targeted-validator",
50
+ "request_schema_id": "gentle-ai.review-targeted-validation-request/v1",
51
+ "result_schema_id": "https://gentle-ai.dev/schema/review/validator/v1",
52
+ "required_capabilities": [
53
+ "gentle-ai.provider-transport/v1"
54
+ ],
55
+ "schema": {
56
+ "path": "schemas/targeted-validator.schema.json",
57
+ "sha256": "58f5efca0fb8089a51e998d5cf07209528a6b6e3782246b34ee1e825132063a8"
58
+ },
59
+ "vector": {
60
+ "path": "vectors/targeted-validator.json",
61
+ "sha256": "7b5a5165e3a913863fb98d2ba5387811860c21333b5c37e6ed3b4e0d121cf2fa"
62
+ }
63
+ }
64
+ ]
65
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://gentle-ai.dev/schema/review/reviewer/v1",
4
+ "title": "Gentle AI reviewer result",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["subject_hash", "inspection", "findings", "evidence"],
8
+ "properties": {
9
+ "subject_hash": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
10
+ "inspection": {"type": "object", "additionalProperties": false, "required": ["status", "paths"], "properties": {"status": {"const": "completed"}, "paths": {"type": "array", "description": "Complete unique unordered set of every changed_path_manifest.path.", "uniqueItems": true, "items": {"type": "string", "minLength": 1}}}},
11
+ "lens": {"type": "string", "description": "Optional selected lens binding. Omission canonicalizes to the selected subject lens.", "enum": ["risk", "resilience", "readability", "reliability", "review-risk", "review-resilience", "review-readability", "review-reliability"]},
12
+ "findings": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["location", "severity", "claim", "proof_refs"], "allOf": [{"if": {"properties": {"severity": {"enum": ["BLOCKER", "CRITICAL"]}}, "required": ["severity"]}, "then": {"required": ["evidence_class", "causal_disposition"]}}], "properties": {"id": {"type": "string", "pattern": "^R[1-4]-[A-Za-z0-9][A-Za-z0-9._-]*$", "description": "Optional explicit ID; omit it to receive a native-assigned ID. When present it must carry the prefix bound to the selected lens, not the selection order: review-risk=R1-, review-readability=R2-, review-reliability=R3-, review-resilience=R4-."}, "lens": {"type": "string", "enum": ["risk", "resilience", "readability", "reliability", "review-risk", "review-resilience", "review-readability", "review-reliability"]}, "location": {"type": "string", "description": "One canonical repository-relative path:line or inclusive path:start-end span.", "pattern": "^.+:[1-9][0-9]*(?:-[1-9][0-9]*)?$"}, "severity": {"type": "string", "enum": ["BLOCKER", "CRITICAL", "WARNING", "SUGGESTION"]}, "claim": {"type": "string", "minLength": 1}, "proof_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "pattern": "\\S", "not": {"pattern": "^\\s*(?:[nN]/[aA]|[nN][aA]|[nN][oO][nN][eE]|[tT][oO][dD][oO]|[tT][bB][dD]|[pP][aA][sS][sS]|[pP][aA][sS][sS][eE][dD]|[sS][uU][cC][cC][eE][sS][sS]|[pP][lL][aA][cC][eE][hH][oO][lL][dD][eE][rR])\\s*$"}}}, "evidence_class": {"type": "string", "enum": ["deterministic", "inferential", "insufficient"]}, "causal_disposition": {"type": "string", "enum": ["introduced", "behavior-activated", "worsened", "pre-existing", "base-only", "unknown"]}}}},
13
+ "evidence": {"type": "array", "minItems": 1, "items": {"type": "string", "pattern": "\\S", "not": {"pattern": "^\\s*(?:[nN]/[aA]|[nN][aA]|[nN][oO][nN][eE]|[tT][oO][dD][oO]|[tT][bB][dD]|[pP][aA][sS][sS]|[pP][aA][sS][sS][eE][dD]|[sS][uU][cC][cC][eE][sS][sS]|[pP][lL][aA][cC][eE][hH][oO][lL][dD][eE][rR])\\s*$"}}}
14
+ },
15
+ "examples": [{"subject_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "inspection": {"status": "completed", "paths": ["internal/example.go"]}, "findings": [], "evidence": ["reviewed the complete candidate scope"]}]
16
+ }
@@ -0,0 +1 @@
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://gentle-ai.dev/schema/review/refuter/v1","title":"Gentle AI refuter result","type":"object","additionalProperties":false,"required":["refuter_request_hash","results"],"properties":{"refuter_request_hash":{"$ref":"#/$defs/sha256"},"results":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["finding_id","outcome","proof_refs"],"properties":{"finding_id":{"type":"string"},"outcome":{"type":"string","enum":["corroborated","refuted","inconclusive"]},"proof_refs":{"type":"array","minItems":1,"items":{"type":"string","pattern":"\\S"}}}}}},"$defs":{"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"examples":[{"refuter_request_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","results":[]}]}
@@ -0,0 +1 @@
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://gentle-ai.dev/schema/review/validator/v1","title":"Gentle AI targeted validator result","type":"object","additionalProperties":false,"required":["targeted_validation_request_hash","correction_target_identity","original_criteria","correction_regression","follow_ups"],"properties":{"targeted_validation_request_hash":{"$ref":"#/$defs/sha256"},"correction_target_identity":{"$ref":"#/$defs/sha256"},"original_criteria":{"$ref":"#/$defs/check"},"correction_regression":{"$ref":"#/$defs/check"},"follow_ups":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["observation","proof_refs"],"properties":{"observation":{"type":"string"},"proof_refs":{"type":"array","minItems":1,"items":{"type":"string","pattern":"\\S"}}}}}},"$defs":{"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"},"check":{"type":"object","additionalProperties":false,"required":["passed","evidence"],"properties":{"passed":{"type":"boolean"},"evidence":{"type":"array","minItems":1,"items":{"type":"string"}}}}},"examples":[{"targeted_validation_request_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","correction_target_identity":"sha256:1111111111111111111111111111111111111111111111111111111111111111","original_criteria":{"passed":true,"evidence":["acceptance test passed"]},"correction_regression":{"passed":true,"evidence":["regression test passed"]},"follow_ups":[]}]}
@@ -0,0 +1 @@
1
+ {"subject_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","inspection":{"status":"completed","paths":["internal/example.go"]},"findings":[],"evidence":["reviewed the complete candidate scope"]}
@@ -0,0 +1 @@
1
+ {"refuter_request_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","results":[]}
@@ -0,0 +1 @@
1
+ {"targeted_validation_request_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","correction_target_identity":"sha256:1111111111111111111111111111111111111111111111111111111111111111","original_criteria":{"passed":true,"evidence":["acceptance test passed"]},"correction_regression":{"passed":true,"evidence":["regression test passed"]},"follow_ups":[]}
@@ -1,17 +1,23 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { createHash } from "node:crypto";
3
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { chmod, mkdir, mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
5
5
  import { tmpdir } from "node:os";
6
- import { basename, isAbsolute, join } from "node:path";
6
+ import { basename, dirname, isAbsolute, join } from "node:path";
7
7
  import test from "node:test";
8
8
  import {
9
9
  GENTLE_AI_BINARY_MISSING_CODE,
10
+ GENTLE_AI_DEV_BINARY_ENV,
10
11
  GENTLE_AI_VERSION,
12
+ gentleAiDevBinaryRegistrationPath,
11
13
  PackageLocalGentleAiBinaryMissingError,
14
+ registerGentleAiDevBinary,
12
15
  resolveGentleAiBinary,
16
+ setGentleAiDevBinaryEnvironmentForTesting,
17
+ unregisterGentleAiDevBinary,
18
+ type GentleAiDevBinaryEnvironment,
13
19
  } from "../lib/gentle-ai-binary.ts";
14
- import { NativeReviewCliV213, createNativeReviewCli, type ExecFileAdapter } from "../lib/native-review-cli.ts";
20
+ import { NativeReviewCliV216, createNativeReviewCli, type ExecFileAdapter } from "../lib/native-review-cli.ts";
15
21
  import { GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM, resolveGentleAiReleaseAsset } from "../scripts/gentle-ai-installer.mjs";
16
22
  import { requireNativeBinary } from "./support/native-binary-gate.ts";
17
23
 
@@ -29,6 +35,47 @@ const nativeBinaryGate = requireNativeBinary({
29
35
  if (!nativeBinaryGate.run) console.log(`gentle-ai-binary: ${nativeBinaryGate.reason}`);
30
36
  const verifiedBinaryTest = nativeBinaryGate.run && process.platform !== "win32" ? test : test.skip;
31
37
 
38
+ interface PinnedBinaryIsolation {
39
+ environment: GentleAiDevBinaryEnvironment;
40
+ savedEnvironmentValue: string | undefined;
41
+ savedRegistration: string | undefined;
42
+ }
43
+
44
+ let pinnedBinaryIsolation: PinnedBinaryIsolation | undefined;
45
+
46
+ test.beforeEach((t) => {
47
+ const home = mkdtempSync(join(tmpdir(), "gentle-pi-pinned-binary-home-"));
48
+ const environment: GentleAiDevBinaryEnvironment = { env: { ...process.env }, home };
49
+ delete environment.env.GENTLE_PI_CONFIG_HOME;
50
+ const savedEnvironmentValue = environment.env[GENTLE_AI_DEV_BINARY_ENV];
51
+ const registrationPath = gentleAiDevBinaryRegistrationPath(environment);
52
+ const savedRegistration = existsSync(registrationPath)
53
+ ? readFileSync(registrationPath, "utf8")
54
+ : undefined;
55
+
56
+ delete environment.env[GENTLE_AI_DEV_BINARY_ENV];
57
+ unregisterGentleAiDevBinary(environment);
58
+ setGentleAiDevBinaryEnvironmentForTesting(environment);
59
+ pinnedBinaryIsolation = { environment, savedEnvironmentValue, savedRegistration };
60
+
61
+ t.after(() => {
62
+ if (savedEnvironmentValue === undefined) {
63
+ delete environment.env[GENTLE_AI_DEV_BINARY_ENV];
64
+ } else {
65
+ environment.env[GENTLE_AI_DEV_BINARY_ENV] = savedEnvironmentValue;
66
+ }
67
+ if (savedRegistration === undefined) {
68
+ unregisterGentleAiDevBinary(environment);
69
+ } else {
70
+ mkdirSync(dirname(registrationPath), { recursive: true });
71
+ writeFileSync(registrationPath, savedRegistration);
72
+ }
73
+ setGentleAiDevBinaryEnvironmentForTesting(undefined);
74
+ pinnedBinaryIsolation = undefined;
75
+ rmSync(home, { recursive: true, force: true });
76
+ });
77
+ });
78
+
32
79
  async function writeVerifiedBinary(packageRoot: string, platform = process.platform): Promise<string> {
33
80
  const asset = resolveGentleAiReleaseAsset(platform, process.arch);
34
81
  const binaryPath = join(packageRoot, ".gentle-ai", RUNTIME_DIRECTORY, asset.executable);
@@ -50,7 +97,7 @@ async function writeWindowsSourceBinary(packageRoot: string): Promise<{ binaryPa
50
97
  method: "go-sumdb-source-build",
51
98
  package: "github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai",
52
99
  module: "github.com/gentleman-programming/gentle-ai/v2",
53
- tag: "v2.2.2",
100
+ tag: "v2.5.0",
54
101
  architecture: process.arch === "x64" ? "x64" : "arm64",
55
102
  binarySha256: createHash("sha256").update(binary).digest("hex"),
56
103
  moduleChecksum: GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM,
@@ -64,13 +111,34 @@ async function writeWindowsSourceBinary(packageRoot: string): Promise<{ binaryPa
64
111
  return { binaryPath, manifestPath };
65
112
  }
66
113
 
67
- verifiedBinaryTest("runtime resolves an absolute package-local binary path without PATH fallback", async () => {
114
+ verifiedBinaryTest("runtime resolves an absolute package-local binary path without PATH fallback or ambient dev contamination", async () => {
68
115
  const packageRoot = await mkdtemp(join(tmpdir(), "gentle-pi-binary-"));
69
116
  const executable = process.platform === "win32" ? "gentle-ai.exe" : "gentle-ai";
70
117
  const binaryPath = await writeVerifiedBinary(packageRoot);
118
+ const devBinary = join(packageRoot, "maintainer-dev-binary");
119
+ await writeFile(devBinary, "maintainer dev binary");
120
+ if (process.platform !== "win32") await chmod(devBinary, 0o700);
121
+ const isolation = pinnedBinaryIsolation;
122
+ assert.ok(isolation, "the pinned-binary fixture must install its isolated environment");
123
+
124
+ const ambientValue = process.env[GENTLE_AI_DEV_BINARY_ENV];
125
+ process.env[GENTLE_AI_DEV_BINARY_ENV] = devBinary;
126
+ try {
127
+ assert.equal(resolveGentleAiBinary(packageRoot, process.platform), binaryPath, "a maintainer's ambient override must not contaminate a pinned-package case");
128
+ } finally {
129
+ if (ambientValue === undefined) delete process.env[GENTLE_AI_DEV_BINARY_ENV];
130
+ else process.env[GENTLE_AI_DEV_BINARY_ENV] = ambientValue;
131
+ }
132
+
133
+ isolation.environment.env[GENTLE_AI_DEV_BINARY_ENV] = devBinary;
134
+ assert.equal(resolveGentleAiBinary(packageRoot, process.platform), devBinary, "an explicit dev-binary test may opt in through the isolated environment seam");
135
+ delete isolation.environment.env[GENTLE_AI_DEV_BINARY_ENV];
136
+ registerGentleAiDevBinary(devBinary, isolation.environment);
137
+ assert.equal(resolveGentleAiBinary(packageRoot, process.platform), devBinary, "an explicit persistent dev registration may opt in through the isolated environment seam");
138
+ assert.equal(unregisterGentleAiDevBinary(isolation.environment), true);
71
139
 
72
140
  const resolved = resolveGentleAiBinary(packageRoot, process.platform);
73
- assert.equal(resolved, binaryPath);
141
+ assert.equal(resolved, binaryPath, "clearing the explicit registration restores the pinned resolver");
74
142
  assert.equal(isAbsolute(resolved), true);
75
143
  assert.equal(basename(resolved), executable);
76
144
  assert.doesNotMatch(resolved, /(^|[/\\])PATH($|[/\\])/i);
@@ -124,7 +192,7 @@ test("runtime rejects an unverified binary, a symlinked manifest, and ambient ex
124
192
  await writeFile(manifestTarget, `${JSON.stringify({ version: GENTLE_AI_VERSION, asset: `gentle-ai_${GENTLE_AI_VERSION}_${process.platform}_${process.arch === "x64" ? "amd64" : process.arch}.tar.gz`, assetSha256: "a".repeat(64), binarySha256 })}\n`);
125
193
  await symlink(manifestTarget, manifestPath);
126
194
  assert.throws(() => resolveGentleAiBinary(packageRoot, process.platform), /package-local-binary-missing/);
127
- assert.throws(() => new NativeReviewCliV213(async () => VERSION, "gentle-ai"), /absolute package-local executable/);
195
+ assert.throws(() => new NativeReviewCliV216(async () => VERSION, "gentle-ai"), /absolute package-local executable/);
128
196
  });
129
197
 
130
198
  verifiedBinaryTest("runtime rejects malformed, unknown, wrong, and symlinked integrity paths", async () => {
@@ -224,16 +292,18 @@ verifiedBinaryTest("production native client never invokes a global gentle-ai ex
224
292
  const calls: string[] = [];
225
293
  const adapter: ExecFileAdapter = async (request) => {
226
294
  calls.push(request.file);
227
- if (request.arguments[0] === "version") return VERSION;
228
295
  return {
229
296
  ...VERSION,
230
- stdout: JSON.stringify({ operation: "review/start", lineage_id: "lineage", state: "reviewing", risk_level: "low", selected_lenses: [], changed_files: 0, changed_lines: 0, correction_budget: 0, action: "created", lenses_required: false, projection: "workspace" }),
297
+ stdout: readFileSync(join(import.meta.dirname, "..", "contracts", "review-integration", "v2", "fixtures", "status.fixture.json"), "utf8"),
231
298
  };
232
299
  };
233
300
 
234
- await createNativeReviewCli(adapter, () => resolveGentleAiBinary(packageRoot, process.platform)).start({ cwd: packageRoot });
235
- assert.deepEqual(calls, [binaryPath, binaryPath]);
301
+ await assert.rejects(
302
+ () => createNativeReviewCli(adapter, () => resolveGentleAiBinary(packageRoot, process.platform)).targetStatus!({ cwd: packageRoot, lineageId: "review-status-fixture" }),
303
+ /schema incompatible/,
304
+ );
305
+ assert.deepEqual(calls, [binaryPath]);
236
306
  assert.ok(calls.every((file) => file !== "gentle-ai"));
237
- assert.throws(() => new NativeReviewCliV213(adapter, "gentle-ai"), /absolute package-local executable/);
238
- assert.throws(() => new NativeReviewCliV213(adapter, "./gentle-ai"), /absolute package-local executable/);
307
+ assert.throws(() => new NativeReviewCliV216(adapter, "gentle-ai"), /absolute package-local executable/);
308
+ assert.throws(() => new NativeReviewCliV216(adapter, "./gentle-ai"), /absolute package-local executable/);
239
309
  });