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
@@ -1,243 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- CAUSAL_DISPOSITION,
5
- COMPACT_EVIDENCE_CLASS,
6
- COMPACT_REVIEW_STATE,
7
- completeCompactCorrection,
8
- completeCompactReview,
9
- completeCompactVerification,
10
- beginCompactCorrection,
11
- createCompactRefuterRequest,
12
- createCompactValidatorRequest,
13
- createCompactReceipt,
14
- freezeCompactValidatorRequest,
15
- createCompactReviewState,
16
- } from "../lib/review-compact.ts";
17
- import { REVIEW_RISK_TIER } from "../lib/review-risk.ts";
18
- import {
19
- REVIEW_MODE,
20
- REVIEW_PROJECTION,
21
- type SnapshotV1,
22
- } from "../lib/review-snapshot.ts";
23
- import { REVIEW_LENS, REVIEW_ROUTE } from "../lib/review-triggers.ts";
24
-
25
- function snapshot(): SnapshotV1 {
26
- return {
27
- schema: "gentle-ai.review-snapshot/v1",
28
- mode: REVIEW_MODE.ORDINARY,
29
- repository_root: "/repo",
30
- base_tree: "1".repeat(40),
31
- complete_snapshot_tree: "2".repeat(40),
32
- review_projection: { kind: REVIEW_PROJECTION.COMPLETE },
33
- initial_review_tree: "2".repeat(40),
34
- genesis_paths: ["src/value.ts"],
35
- intended_untracked: [],
36
- diff_evidence: {
37
- event: "ordinary-start",
38
- changedLines: 10,
39
- triviality: "unproven",
40
- evidenceComplete: true,
41
- executableChanged: true,
42
- configurationChanged: false,
43
- hotPathChanged: false,
44
- riskSignal: false,
45
- resilienceSignal: false,
46
- reliabilitySignal: false,
47
- },
48
- route: REVIEW_ROUTE.STANDARD,
49
- lenses: [REVIEW_LENS.READABILITY],
50
- risk_tier: REVIEW_RISK_TIER.MEDIUM,
51
- original_changed_lines: 10,
52
- correction_budget: 5,
53
- policy_hash: "a".repeat(64),
54
- object_store: {
55
- snapshot_directory: "/tmp/snapshot",
56
- object_directory: "/tmp/snapshot/objects",
57
- alternate_object_directory: "/repo/.git/objects",
58
- metadata_path: "/tmp/snapshot/snapshot.json",
59
- sensitivity: "workspace-content",
60
- cleanup_trigger: "lineage-terminal",
61
- cleanup_action: "delete-isolated-object-store",
62
- },
63
- };
64
- }
65
-
66
- test("causal review assigns missing IDs and admits only proven candidate-caused severe findings", () => {
67
- const reviewing = createCompactReviewState({
68
- lineageId: "compact-causal",
69
- snapshot: snapshot(),
70
- policyHash: "a".repeat(64),
71
- });
72
- const completed = completeCompactReview(reviewing, {
73
- lens_results: [{
74
- findings: [
75
- {
76
- location: "src/value.ts:2",
77
- severity: "CRITICAL",
78
- claim: "The candidate activates an invalid branch.",
79
- evidence_class: COMPACT_EVIDENCE_CLASS.DETERMINISTIC,
80
- causal_disposition: CAUSAL_DISPOSITION.BEHAVIOR_ACTIVATED,
81
- proof_refs: ["changed-hunk:src/value.ts:2"],
82
- },
83
- {
84
- location: "src/value.ts:1",
85
- severity: "BLOCKER",
86
- claim: "The base already contains a separate defect.",
87
- evidence_class: COMPACT_EVIDENCE_CLASS.DETERMINISTIC,
88
- causal_disposition: CAUSAL_DISPOSITION.PRE_EXISTING,
89
- proof_refs: ["before-after:base-and-candidate"],
90
- },
91
- ],
92
- evidence: ["reviewed exact candidate tree"],
93
- }],
94
- });
95
-
96
- assert.equal(completed.state, COMPACT_REVIEW_STATE.CORRECTION_REQUIRED);
97
- assert.deepEqual(completed.correction_ids, ["READABILITY-002"]);
98
- assert.equal(completed.follow_ups.length, 1);
99
- assert.equal(completed.follow_ups[0]?.finding_id, "READABILITY-001");
100
- });
101
-
102
- test("unknown, malformed, insufficient, and incomplete inferential severe claims escalate", () => {
103
- const reviewing = createCompactReviewState({
104
- lineageId: "compact-escalation",
105
- snapshot: snapshot(),
106
- policyHash: "a".repeat(64),
107
- });
108
- const lensResults = [{
109
- findings: [{
110
- location: "src/value.ts:2",
111
- severity: "CRITICAL",
112
- claim: "The candidate may activate an invalid branch.",
113
- evidence_class: COMPACT_EVIDENCE_CLASS.INFERENTIAL,
114
- causal_disposition: CAUSAL_DISPOSITION.INTRODUCED,
115
- proof_refs: ["differential-test:tests/value.test.ts"],
116
- }],
117
- evidence: [],
118
- }];
119
- const completed = completeCompactReview(reviewing, {
120
- lens_results: lensResults,
121
- refuter_request_hash: createCompactRefuterRequest(reviewing, lensResults)?.request_hash,
122
- });
123
- assert.equal(completed.state, COMPACT_REVIEW_STATE.ESCALATED);
124
- assert.match(completed.escalation_reasons.join("\n"), /complete refuter batch/i);
125
- });
126
-
127
- test("refuter request assigns native IDs and rejects incomplete or foreign batches", () => {
128
- const input = { lens_results: [{ findings: [{
129
- location: "src/value.ts:2", severity: "CRITICAL", claim: "The branch may fail.",
130
- evidence_class: "inferential", causal_disposition: "introduced",
131
- proof_refs: ["differential-test:tests/value.test.ts"],
132
- }], evidence: [] }] };
133
- for (const rows of [[], [
134
- { finding_id: "READABILITY-001", outcome: "refuted", proof_refs: ["before-after:proof"] },
135
- { finding_id: "READABILITY-001", outcome: "refuted", proof_refs: ["before-after:proof"] },
136
- ], [{ finding_id: "FOREIGN-001", outcome: "refuted", proof_refs: ["before-after:proof"] }]]) {
137
- const reviewing = createCompactReviewState({ lineageId: `refuter-${rows.length}-${rows[0]?.finding_id ?? "empty"}`, snapshot: snapshot(), policyHash: "a".repeat(64) });
138
- const request = createCompactRefuterRequest(reviewing, input.lens_results);
139
- assert.deepEqual(request?.findings.map(({ id }) => id), ["READABILITY-001"]);
140
- const completed = completeCompactReview(reviewing, { ...input, refuter_request_hash: request?.request_hash, refuter_results: rows });
141
- assert.equal(completed.state, COMPACT_REVIEW_STATE.ESCALATED);
142
- }
143
- });
144
-
145
- test("informational malformed and duplicate IDs are replaced without escalation", () => {
146
- const completed = completeCompactReview(createCompactReviewState({ lineageId: "informational-ids", snapshot: snapshot(), policyHash: "a".repeat(64) }), {
147
- lens_results: [{ findings: [
148
- { id: "bad", location: "src/value.ts:1", severity: "WARNING", claim: "Info.", proof_refs: [] },
149
- { id: "READABILITY-010", location: "src/value.ts:2", severity: "WARNING", claim: "Info.", proof_refs: [] },
150
- { id: "READABILITY-010", location: "src/value.ts:3", severity: "SUGGESTION", claim: "Info.", proof_refs: [] },
151
- { id: "also-bad", location: "src/value.ts:4", severity: "CRITICAL", claim: "Severe.", evidence_class: "deterministic", causal_disposition: "introduced", proof_refs: ["changed-hunk:src/value.ts:4"] },
152
- ], evidence: [] }],
153
- });
154
- assert.equal(completed.state, COMPACT_REVIEW_STATE.ESCALATED);
155
- assert.equal(completed.escalation_reasons.length, 1);
156
- assert.match(completed.escalation_reasons[0] ?? "", /ALSO-BAD/);
157
- for (const finding of completed.findings.filter(({ severity }) => severity === "WARNING" || severity === "SUGGESTION")) {
158
- assert.equal(completed.outcomes[finding.id], "info");
159
- }
160
- });
161
-
162
- test("one forecast, one repository-sized correction, one targeted validator, and final evidence close the lineage", () => {
163
- const reviewed = completeCompactReview(createCompactReviewState({
164
- lineageId: "compact-correction",
165
- snapshot: snapshot(),
166
- policyHash: "a".repeat(64),
167
- }), {
168
- lens_results: [{
169
- findings: [{
170
- id: "READABILITY-009",
171
- location: "src/value.ts:2",
172
- severity: "BLOCKER",
173
- claim: "The candidate removes the required guard.",
174
- evidence_class: "deterministic",
175
- causal_disposition: "introduced",
176
- proof_refs: ["changed-hunk:src/value.ts:2"],
177
- }],
178
- evidence: [],
179
- }],
180
- });
181
- const forecast = beginCompactCorrection(reviewed, 3);
182
- const correction = {
183
- candidate_tree: "3".repeat(40),
184
- changed_paths: ["src/value.ts"],
185
- changed_lines: 3,
186
- fix_diff: "diff --git a/src/value.ts b/src/value.ts",
187
- fix_diff_hash: "b".repeat(64),
188
- };
189
- const proof = {
190
- original_criteria: { passed: true, evidence: ["original suite passed"] },
191
- correction_regression: { passed: true, evidence: ["guard regression passed"] },
192
- };
193
- const request = createCompactValidatorRequest(forecast, correction);
194
- const frozen = freezeCompactValidatorRequest(forecast, request);
195
- const validation = { request_hash: request.request_hash, correction_ids: ["READABILITY-009"], ...proof, fix_caused_findings: [], follow_ups: [] };
196
- assert.throws(() => completeCompactCorrection(frozen, { ...correction, candidate_tree: "4".repeat(40) }, [], validation), /frozen validator request/i);
197
- assert.equal(completeCompactCorrection(frozen, correction, [], { ...validation, original_criteria: { passed: false, evidence: ["independent acceptance failure"] } }).state, COMPACT_REVIEW_STATE.ESCALATED);
198
- const corrected = completeCompactCorrection(frozen, correction, [], validation);
199
- assert.equal(corrected.state, COMPACT_REVIEW_STATE.VALIDATING);
200
- const terminal = completeCompactVerification(corrected, "full suite passed", true);
201
- assert.equal(terminal.state, COMPACT_REVIEW_STATE.APPROVED);
202
- const receipt = createCompactReceipt(terminal, "c".repeat(64));
203
- assert.equal(receipt.body.original_changed_lines, 10);
204
- assert.equal(receipt.body.correction_budget, 5);
205
- assert.deepEqual(receipt.body.correction_ids, ["READABILITY-009"]);
206
- assert.match(receipt.body.evidence_hash, /^[0-9a-f]{64}$/);
207
- });
208
-
209
- test("correction forecast and actual repository evidence cannot exceed the frozen budget", () => {
210
- const reviewed = completeCompactReview(createCompactReviewState({
211
- lineageId: "compact-budget",
212
- snapshot: snapshot(),
213
- policyHash: "a".repeat(64),
214
- }), {
215
- lens_results: [{
216
- findings: [{
217
- location: "src/value.ts:2",
218
- severity: "BLOCKER",
219
- claim: "The candidate removes the required guard.",
220
- evidence_class: "deterministic",
221
- causal_disposition: "introduced",
222
- proof_refs: ["changed-hunk:src/value.ts:2"],
223
- }],
224
- evidence: [],
225
- }],
226
- });
227
- assert.throws(() => beginCompactCorrection(reviewed, 0), /positive/);
228
- const overBudget = beginCompactCorrection(reviewed, 6);
229
- assert.equal(overBudget.state, COMPACT_REVIEW_STATE.ESCALATED);
230
- const forecast = beginCompactCorrection(reviewed, 5);
231
- assert.throws(() => completeCompactCorrection(forecast, {
232
- candidate_tree: "3".repeat(40),
233
- changed_paths: ["src/value.ts"],
234
- changed_lines: 6,
235
- fix_diff: "diff",
236
- fix_diff_hash: "b".repeat(64),
237
- }, [], {
238
- correction_ids: forecast.correction_ids,
239
- original_criteria: { passed: true, evidence: ["passed"] },
240
- correction_regression: { passed: true, evidence: ["passed"] },
241
- follow_ups: [],
242
- }), /exceeding frozen budget/i);
243
- });
@@ -1,89 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { normalizeRefuterBatch } from "../lib/review-refuter-adapter.ts";
4
- import type { CompactRefuterRequest } from "../lib/review-compact.ts";
5
-
6
- const request: CompactRefuterRequest = {
7
- request_hash: "a".repeat(64),
8
- findings: [
9
- {
10
- id: "READABILITY-001",
11
- lens: "review-readability",
12
- location: "lib/value.ts:1",
13
- severity: "CRITICAL",
14
- claim: "The value may be invalid.",
15
- evidence_class: "inferential",
16
- causal_disposition: "introduced",
17
- proof_refs: ["changed-hunk:lib/value.ts:1"],
18
- },
19
- ],
20
- };
21
-
22
- test("refuter adapter normalizes only the exact complete frozen batch", () => {
23
- const normalized = normalizeRefuterBatch(request, {
24
- schema: "gentle-ai.refuter-result-batch/v1",
25
- request_hash: request.request_hash,
26
- results: [{
27
- finding_id: "READABILITY-001",
28
- outcome: "refuted",
29
- proof_refs: ["changed-hunk:lib/value.ts:1"],
30
- }],
31
- });
32
-
33
- assert.deepEqual(normalized, {
34
- status: "normalized",
35
- refuter_request_hash: request.request_hash,
36
- refuter_results: [{
37
- finding_id: "READABILITY-001",
38
- outcome: "refuted",
39
- proof_refs: ["changed-hunk:lib/value.ts:1"],
40
- }],
41
- });
42
- });
43
-
44
- test("refuter adapter preserves published inconclusive outcomes", () => {
45
- const normalized = normalizeRefuterBatch(request, {
46
- schema: "gentle-ai.refuter-result-batch/v1",
47
- request_hash: request.request_hash,
48
- results: [{ finding_id: "READABILITY-001", outcome: "inconclusive", proof_refs: ["changed-hunk:lib/value.ts:1"] }],
49
- });
50
- assert.equal(normalized.status, "normalized");
51
- assert.equal(normalized.status === "normalized" && normalized.refuter_results[0]?.outcome, "inconclusive");
52
- });
53
-
54
- test("refuter adapter accepts independent concrete refuter proof", () => {
55
- const normalized = normalizeRefuterBatch(request, {
56
- schema: "gentle-ai.refuter-result-batch/v1",
57
- request_hash: request.request_hash,
58
- results: [{
59
- finding_id: "READABILITY-001",
60
- outcome: "refuted",
61
- proof_refs: ["differential-test:independent reproduction passes"],
62
- }],
63
- });
64
-
65
- assert.equal(normalized.status, "normalized");
66
- assert.deepEqual(normalized.status === "normalized" && normalized.refuter_results[0]?.proof_refs, [
67
- "differential-test:independent reproduction passes",
68
- ]);
69
- });
70
-
71
- test("refuter adapter rejects prose, aliases, invalid outcomes, and empty or malformed proof", () => {
72
- for (const batch of [
73
- `prose ${JSON.stringify({ schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [] })}`,
74
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [{ id: "READABILITY-001", resolution: "refuted", proof_refs: ["changed-hunk:lib/value.ts:1"] }] },
75
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [{ finding_id: "READABILITY-001", outcome: "refuted", proof_refs: [] }] },
76
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [{ finding_id: "READABILITY-001", outcome: "refuted", proof_refs: [""] }] },
77
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [{ finding_id: "READABILITY-001", outcome: "refuted", proof_refs: [" untrimmed proof"] }] },
78
- ]) assert.equal(normalizeRefuterBatch(request, batch).status, "invalid");
79
- });
80
-
81
- test("refuter adapter rejects wrong hashes and incomplete, duplicate, or extra frozen IDs", () => {
82
- const row = { finding_id: "READABILITY-001", outcome: "refuted", proof_refs: ["changed-hunk:lib/value.ts:1"] };
83
- for (const batch of [
84
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: "b".repeat(64), results: [row] },
85
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [] },
86
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [row, row] },
87
- { schema: "gentle-ai.refuter-result-batch/v1", request_hash: request.request_hash, results: [{ ...row, finding_id: "READABILITY-002" }] },
88
- ]) assert.equal(normalizeRefuterBatch(request, batch).status, "invalid");
89
- });