gentle-pi 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/README.md +70 -12
  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 -1
  7. package/assets/agents/review-reliability.md +4 -1
  8. package/assets/agents/review-resilience.md +4 -1
  9. package/assets/agents/review-risk.md +4 -1
  10. package/assets/agents/sdd-apply.md +6 -1
  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 +6 -1
  17. package/assets/agents/sdd-spec.md +6 -1
  18. package/assets/agents/sdd-status.md +6 -1
  19. package/assets/agents/sdd-sync.md +6 -1
  20. package/assets/agents/sdd-tasks.md +6 -1
  21. package/assets/agents/sdd-verify.md +6 -1
  22. package/assets/chains/4r-review.chain.md +2 -0
  23. package/assets/chains/sdd-full.chain.md +1 -1
  24. package/assets/chains/sdd-plan.chain.md +1 -1
  25. package/assets/chains/sdd-verify.chain.md +1 -1
  26. package/assets/orchestrator-delegation.md +246 -67
  27. package/assets/orchestrator.md +7 -14
  28. package/assets/sdd-orchestrator-workflow.md +154 -9
  29. package/assets/support/sdd-status-contract.md +19 -1
  30. package/contracts/review-integration/v1/fixtures/consent.fixture.json +3 -3
  31. package/contracts/review-integration/v1/fixtures/start-v2.fixture.json +19 -28
  32. package/contracts/review-integration/v1/fixtures/start.fixture.json +1 -10
  33. package/contracts/review-integration/v1/fixtures/status-v2.fixture.json +12 -21
  34. package/contracts/review-integration/v1/schemas/correction-plan-request.schema.json +49 -0
  35. package/contracts/review-integration/v1/schemas/operation.schema.json +76 -0
  36. package/contracts/review-integration/v1/schemas/repair.schema.json +39 -0
  37. package/contracts/review-integration/v1/schemas/status-v2.schema.json +4 -2
  38. package/contracts/review-integration/v1/schemas/status.schema.json +4 -2
  39. package/contracts/review-integration/v2/fixtures/consent.fixture.json +1 -1
  40. package/contracts/review-integration/v2/fixtures/start.fixture.json +1 -10
  41. package/contracts/review-integration/v2/fixtures/status.fixture.json +1 -10
  42. package/contracts/review-integration/v2/schemas/failure.schema.json +5 -1
  43. package/contracts/review-integration/v2/schemas/operation.schema.json +6 -1
  44. package/contracts/review-integration/v2/schemas/repair.schema.json +4 -2
  45. package/contracts/review-integration/v2/schemas/start.schema.json +5 -2
  46. package/contracts/review-integration/v2/schemas/status.schema.json +4 -2
  47. package/contracts/review-provider-contract-mirror/provider-contract.lock.json +30 -0
  48. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/README.md +12 -0
  49. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/manifest.json +65 -0
  50. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/lens.schema.json +16 -0
  51. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/refuter.schema.json +1 -0
  52. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/targeted-validator.schema.json +1 -0
  53. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/lens.json +1 -0
  54. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/refuter.json +1 -0
  55. package/contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/targeted-validator.json +1 -0
  56. package/contracts/review-provider-contract-mirror/v1.1.0/generated/provider-capabilities.baseline.json +15 -0
  57. package/contracts/review-provider-contract-mirror/v1.1.0/generated/provider-roles.baseline.json +42 -0
  58. package/docs/native-authority-architecture.md +5 -5
  59. package/docs/review-integration.md +22 -2
  60. package/extensions/gentle-ai.ts +1595 -201
  61. package/extensions/sdd-init.ts +19 -6
  62. package/extensions/skill-registry.ts +10 -2
  63. package/extensions/startup-banner.ts +10 -4
  64. package/lib/gentle-ai-binary.ts +173 -2
  65. package/lib/git-commit-transaction.ts +77 -17
  66. package/lib/native-review-cli.ts +528 -65
  67. package/lib/provider-contract-bundle.ts +704 -0
  68. package/lib/review-candidate-view.ts +527 -18
  69. package/lib/review-compact-contract.ts +59 -248
  70. package/lib/review-host-relay.ts +436 -0
  71. package/lib/review-integration-v2.ts +537 -36
  72. package/lib/review-relay-contract.ts +16 -0
  73. package/lib/sdd-preflight.ts +53 -1
  74. package/package.json +5 -2
  75. package/runtime/gentle-ai-binary.mjs +173 -2
  76. package/runtime/git-commit-transaction.mjs +75 -15
  77. package/runtime/native-review-cli.mjs +524 -61
  78. package/runtime/review-integration-v2.mjs +536 -35
  79. package/runtime/review-relay-contract.mjs +17 -0
  80. package/scripts/build-git-commit-transaction-runner.mjs +1 -0
  81. package/scripts/check-provider-contract.mjs +138 -0
  82. package/scripts/gentle-ai-installer.mjs +23 -13
  83. package/scripts/maintainer/provider-relay-matrix.mjs +219 -0
  84. package/scripts/mirror-provider-contract.mjs +143 -0
  85. package/scripts/test-packed-runner.mjs +16 -2
  86. package/scripts/verify-package-files.mjs +110 -33
  87. package/skills/_shared/review-ledger-contract.md +4 -6
  88. package/skills/gentle-ai/SKILL.md +4 -4
  89. package/skills/issue-creation/SKILL.md +94 -168
  90. package/skills/judgment-day/SKILL.md +7 -1
  91. package/skills/judgment-day/references/prompts-and-formats.md +2 -0
  92. package/skills/rdd-defect-workflow/SKILL.md +54 -0
  93. package/tests/background-subagents.test.ts +771 -0
  94. package/tests/crosslane/cross-lane.mjs +1169 -0
  95. package/tests/delegated-key-learnings-contract.test.ts +238 -0
  96. package/tests/fixtures/devbinary/capabilities-v2.1.derived.json +331 -0
  97. package/tests/fixtures/devbinary/capabilities-v2.2.captured.json +340 -0
  98. package/tests/fixtures/devbinary/consent-v3.captured.json +37 -0
  99. package/tests/fixtures/devbinary/failure-v2-capture-evidence.captured.json +16 -0
  100. package/tests/fixtures/devbinary/result-artifact-v2-path.captured.json +12 -0
  101. package/tests/fixtures/devbinary/result-artifact-v2.captured.json +12 -0
  102. package/tests/fixtures/devbinary/start-v3-consent-declined.captured.json +19 -0
  103. package/tests/fixtures/devbinary/start-v3-consent-granted.captured.json +109 -0
  104. package/tests/fixtures/devbinary/status-v5-capture-result-submission.captured.json +184 -0
  105. package/tests/fixtures/devbinary/status-v5-repository-context.captured.json +138 -0
  106. package/tests/fixtures/devbinary/status-v5.captured.json +88 -0
  107. package/tests/fixtures/provider-contract-bundle/v1.1.0/README.md +12 -0
  108. package/tests/fixtures/provider-contract-bundle/v1.1.0/manifest.json +65 -0
  109. package/tests/fixtures/provider-contract-bundle/v1.1.0/schemas/lens.schema.json +16 -0
  110. package/tests/fixtures/provider-contract-bundle/v1.1.0/schemas/refuter.schema.json +1 -0
  111. package/tests/fixtures/provider-contract-bundle/v1.1.0/schemas/targeted-validator.schema.json +1 -0
  112. package/tests/fixtures/provider-contract-bundle/v1.1.0/vectors/lens.json +1 -0
  113. package/tests/fixtures/provider-contract-bundle/v1.1.0/vectors/refuter.json +1 -0
  114. package/tests/fixtures/provider-contract-bundle/v1.1.0/vectors/targeted-validator.json +1 -0
  115. package/tests/gentle-ai-binary.test.ts +1 -1
  116. package/tests/gentle-ai-dev-binary-surfacing.test.ts +195 -0
  117. package/tests/gentle-ai-dev-binary.test.ts +336 -0
  118. package/tests/gentle-ai-installer.test.ts +46 -46
  119. package/tests/git-commit-transaction.test.ts +229 -1
  120. package/tests/maintainer/provider-relay.maintest.ts +265 -0
  121. package/tests/native-review-capability-contract.test.ts +48 -2
  122. package/tests/native-review-cli.test.ts +56 -0
  123. package/tests/native-review-consent.test.ts +164 -3
  124. package/tests/native-review-parity-runtime.test.ts +37 -0
  125. package/tests/native-review-parity.test.ts +218 -15
  126. package/tests/native-sdd-attempt-authority.test.ts +235 -0
  127. package/tests/orchestrator-budget.test.ts +30 -5
  128. package/tests/package-manifest.test.ts +98 -72
  129. package/tests/provider-contract-bundle.test.ts +385 -0
  130. package/tests/provider-contract-mirror.test.ts +206 -0
  131. package/tests/provider-defect-handoff.test.ts +355 -0
  132. package/tests/review-actor-tool-deny.test.ts +12 -13
  133. package/tests/review-candidate-view.test.ts +489 -9
  134. package/tests/review-compact-contract.test.ts +52 -119
  135. package/tests/review-controller-native-recovery.test.ts +643 -47
  136. package/tests/review-controller-native-routing.test.ts +1667 -222
  137. package/tests/review-controller-workspace-root.test.ts +17 -2
  138. package/tests/review-corrected-finalize-binding.test.ts +175 -0
  139. package/tests/review-dispatch-hydration-gap.test.ts +197 -0
  140. package/tests/review-host-relay-routing.test.ts +317 -0
  141. package/tests/review-host-relay.test.ts +520 -0
  142. package/tests/review-integration-v2-forward.test.ts +631 -0
  143. package/tests/review-integration-v2.test.ts +114 -0
  144. package/tests/review-ledger-contract.test.ts +12 -28
  145. package/tests/review-recovered-lineage-routing.test.ts +246 -0
  146. package/tests/review-relay-transport-agent.test.ts +249 -0
  147. package/tests/runtime-harness.mjs +242 -14
  148. package/tests/sdd-agent-tools.test.ts +18 -33
  149. package/tests/skill-collision-prefixes.test.ts +1 -0
  150. package/tests/skill-registry.test.ts +50 -1
  151. package/tests/verify-package-files.test.ts +62 -0
  152. package/assets/agents/review-refuter.md +0 -40
  153. package/assets/agents/review-validator.md +0 -23
  154. package/lib/native-review-remediation.ts +0 -49
  155. package/lib/review-compact.ts +0 -947
  156. package/lib/review-refuter-adapter.ts +0 -129
  157. package/lib/review-runtime-contract.ts +0 -68
  158. package/prompts/gcl.md +0 -54
  159. package/prompts/gis.md +0 -25
  160. package/prompts/gpr.md +0 -41
  161. package/prompts/gwr.md +0 -31
  162. package/tests/fixtures/native-review-cli/v2.1.2/bind-sdd.json +0 -25
  163. package/tests/fixtures/native-review-cli/v2.1.2/finalize.json +0 -8
  164. package/tests/fixtures/native-review-cli/v2.1.2/sdd-status-engram.json +0 -139
  165. package/tests/fixtures/native-review-cli/v2.1.2/sdd-status.json +0 -200
  166. package/tests/fixtures/native-review-cli/v2.1.2/start.json +0 -12
  167. package/tests/fixtures/native-review-cli/v2.1.2/validate-allow.json +0 -24
  168. package/tests/fixtures/native-review-cli/v2.1.2/validate-deny-empty-context.json +0 -20
  169. package/tests/fixtures/native-review-cli/v2.1.2/validate-deny.json +0 -28
  170. package/tests/review-compact.test.ts +0 -243
  171. package/tests/review-refuter-adapter.test.ts +0 -89
@@ -1,200 +0,0 @@
1
- {
2
- "schemaName": "gentle-ai.sdd-status",
3
- "schemaVersion": 1,
4
- "changeName": "native-review-authority-parity",
5
- "artifactStore": "openspec",
6
- "planningHome": {
7
- "mode": "repo-local",
8
- "path": "/tmp/gentle-ai-v212-contract-9XGIB4/openspec"
9
- },
10
- "changeRoot": "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity",
11
- "artifactPaths": {
12
- "proposal": [
13
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/proposal.md"
14
- ],
15
- "specs": [
16
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/specs/review/spec.md"
17
- ],
18
- "design": [
19
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/design.md"
20
- ],
21
- "tasks": [
22
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/tasks.md"
23
- ],
24
- "applyProgress": [],
25
- "verifyReport": [
26
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/verify-report.md"
27
- ],
28
- "reviewPolicy": [],
29
- "reviewLedger": [],
30
- "reviewReceipt": [],
31
- "reviewBundle": [],
32
- "reviewContext": [],
33
- "reviewState": [
34
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/reviews/transaction.json"
35
- ]
36
- },
37
- "contextFiles": {
38
- "proposal": [
39
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/proposal.md"
40
- ],
41
- "specs": [
42
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/specs/review/spec.md"
43
- ],
44
- "design": [
45
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/design.md"
46
- ],
47
- "tasks": [
48
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/tasks.md"
49
- ],
50
- "applyProgress": [],
51
- "verifyReport": [
52
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/verify-report.md"
53
- ],
54
- "reviewPolicy": [],
55
- "reviewLedger": [],
56
- "reviewReceipt": [],
57
- "reviewBundle": [],
58
- "reviewContext": [],
59
- "reviewState": [
60
- "/tmp/gentle-ai-v212-contract-9XGIB4/openspec/changes/native-review-authority-parity/reviews/transaction.json"
61
- ]
62
- },
63
- "artifacts": {
64
- "applyProgress": "missing",
65
- "design": "done",
66
- "proposal": "done",
67
- "reviewBundle": "missing",
68
- "reviewContext": "missing",
69
- "reviewLedger": "missing",
70
- "reviewReceipt": "missing",
71
- "reviewState": "done",
72
- "specs": "done",
73
- "tasks": "done",
74
- "verifyReport": "done"
75
- },
76
- "taskProgress": {
77
- "total": 1,
78
- "completed": 1,
79
- "pending": 0,
80
- "allComplete": true
81
- },
82
- "dependencies": {
83
- "proposal": "all_done",
84
- "specs": "all_done",
85
- "design": "all_done",
86
- "tasks": "all_done",
87
- "apply": "all_done",
88
- "verify": "all_done",
89
- "archive": "ready"
90
- },
91
- "applyState": "all_done",
92
- "actionContext": {
93
- "mode": "repo-local",
94
- "workspaceRoot": "/tmp/gentle-ai-v212-contract-9XGIB4",
95
- "allowedEditRoots": [
96
- "/tmp/gentle-ai-v212-contract-9XGIB4"
97
- ]
98
- },
99
- "relationships": {
100
- "dependsOn": [],
101
- "supersedes": [],
102
- "amends": [],
103
- "conflictsWith": [],
104
- "sameDomainActiveChanges": []
105
- },
106
- "remediationState": {
107
- "required": false,
108
- "complete": false,
109
- "failedEvidenceRevision": "",
110
- "lineageId": "",
111
- "generation": 0,
112
- "fixBatch": 0,
113
- "reason": ""
114
- },
115
- "reviewGate": {
116
- "result": "allow",
117
- "reason": "explicit bound compact authority exactly matches the current repository"
118
- },
119
- "reviewTransaction": {
120
- "schema": "gentle-ai.review-transaction/v1",
121
- "lineage_id": "issue-1099-corrected-candidate-review-20260710",
122
- "mode": "ordinary_4r",
123
- "generation": 1,
124
- "state": "reviewing",
125
- "snapshot": {
126
- "kind": "current-changes",
127
- "base_tree": "ba040f17cdcd2a5960361971eaff79684c48847a",
128
- "candidate_tree": "5bc2f4bdd086d064bc3ada255f16c631facc6839",
129
- "paths_digest": "sha256:4a52771035fe6ef25f0155b11c052a661879b1cd1af4bbe5cd337118a9dd29dd",
130
- "intended_untracked": [
131
- "assets/agents/gentle-ai-explore.md",
132
- "assets/agents/gentle-ai-verify.md"
133
- ],
134
- "intended_untracked_proof": "sha256:ea65650186e3d14ed53ae4912a2a30127863fe9aec0e4c14050e4fa154b0bfa3",
135
- "paths": [
136
- "assets/agents/gentle-ai-explore.md",
137
- "assets/agents/gentle-ai-verify.md",
138
- "assets/orchestrator-delegation.md",
139
- "assets/orchestrator.md",
140
- "tests/package-manifest.test.ts",
141
- "tests/sdd-agent-tools.test.ts"
142
- ],
143
- "identity": "sha256:d88627d276b790d1ed58abc44118d1d95a9620d9755d5e61c8fbda0f97cea53c"
144
- },
145
- "base_tree": "ba040f17cdcd2a5960361971eaff79684c48847a",
146
- "paths_digest": "sha256:4a52771035fe6ef25f0155b11c052a661879b1cd1af4bbe5cd337118a9dd29dd",
147
- "initial_review_tree": "5bc2f4bdd086d064bc3ada255f16c631facc6839",
148
- "final_candidate_tree": "5bc2f4bdd086d064bc3ada255f16c631facc6839",
149
- "fix_delta_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
150
- "policy_hash": "sha256:9197a98b8c5ceac34da4e8d213908d68023f215e891ecb85dfe9fb0b355f9482",
151
- "ledger_hash": "",
152
- "ledger_findings_hash": "",
153
- "evidence_hash": "",
154
- "judge_proofs": [],
155
- "counters": {
156
- "full_reviews": 1,
157
- "refuter_batches": 0,
158
- "fix_batches": 0,
159
- "scoped_fix_validations": 0,
160
- "final_verifications": 0,
161
- "fix_rounds": 0,
162
- "scoped_rejudgments": 0,
163
- "judge_executions": 0
164
- },
165
- "findings": [],
166
- "classifications": {},
167
- "outcomes": {},
168
- "fix_finding_ids": [],
169
- "pending_refuter_ids": [],
170
- "fix_caused_findings": [],
171
- "follow_ups": []
172
- },
173
- "phaseInstructions": {
174
- "apply": [
175
- "Change: native-review-authority-parity",
176
- "State: all_done",
177
- "Read proposal, specs, design, and tasks before editing.",
178
- "Implement only unchecked tasks and update tasks.md checkboxes as work completes."
179
- ],
180
- "verify": [
181
- "Change: native-review-authority-parity",
182
- "State: all_done",
183
- "Verify implementation against proposal, specs, design, and task completion.",
184
- "Run final verification only after every task is complete; apply-progress never makes final verification ready."
185
- ],
186
- "remediate": [
187
- "Change: native-review-authority-parity",
188
- "Remediation is allowed only when the persisted review transaction has remaining mode-specific budget.",
189
- "Bind focused tests, runtime harness evidence, and rollback evidence to the exact failed evidence revision.",
190
- "A bare remediation envelope or stale failed revision never completes remediation."
191
- ],
192
- "archive": [
193
- "Change: native-review-authority-parity",
194
- "State: ready",
195
- "Archive only when verify-report.md exists and every task checkbox is complete."
196
- ]
197
- },
198
- "nextRecommended": "archive",
199
- "blockedReasons": []
200
- }
@@ -1,12 +0,0 @@
1
- {
2
- "operation": "review/start",
3
- "lineage_id": "lineage-1",
4
- "state": "reviewing",
5
- "risk_level": "medium",
6
- "selected_lenses": [
7
- "review-reliability"
8
- ],
9
- "changed_files": 1,
10
- "changed_lines": 2,
11
- "correction_budget": 1
12
- }
@@ -1,24 +0,0 @@
1
- {
2
- "schema": "gentle-ai.review-gate-result/v1",
3
- "result": "allow",
4
- "allowed": true,
5
- "action": "continue",
6
- "reason": "authoritative transaction, current repository target, and content-bound artifacts match",
7
- "context": {
8
- "gate": "post-apply",
9
- "lineage_id": "issue136-contract-runtime",
10
- "generation": 1,
11
- "store_revision": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
12
- "genesis_revision": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
13
- "chain_identity": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
14
- "bundle_digest": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
15
- "base_tree": "cb234a1435871ed095db961750b8bb944fadbd43",
16
- "candidate_tree": "3f8acce95a176230e45398698722eaee3091d625",
17
- "paths_digest": "sha256:0cc3964e29bb296c5f17bc496325961ed0df989b5333ac20d05770776a34be52",
18
- "fix_delta_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
19
- "policy_hash": "sha256:34fb63d7f29f8613cd4431382b1057398a4816f8a4c20fc34677fffc80a184f6",
20
- "ledger_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
21
- "evidence_hash": "sha256:2fa17828f842a4043ff7be11e4f439f40c6b06e1275538b6b4c800a27446f9d9",
22
- "base_relationship_valid": true
23
- }
24
- }
@@ -1,20 +0,0 @@
1
- {
2
- "schema": "gentle-ai.review-gate-result/v1",
3
- "result": "invalidated",
4
- "allowed": false,
5
- "action": "explicit-maintainer-action",
6
- "reason": "compact gate inputs cannot be derived: configured upstream is missing or ambiguous; pass --base-ref \u003cremote\u003e/\u003cbranch\u003e",
7
- "context": {
8
- "gate": "",
9
- "lineage_id": "",
10
- "generation": 0,
11
- "base_tree": "",
12
- "candidate_tree": "",
13
- "paths_digest": "",
14
- "fix_delta_hash": "",
15
- "policy_hash": "",
16
- "ledger_hash": "",
17
- "evidence_hash": "",
18
- "base_relationship_valid": false
19
- }
20
- }
@@ -1,28 +0,0 @@
1
- {
2
- "schema": "gentle-ai.review-gate-result/v1",
3
- "result": "scope-changed",
4
- "allowed": false,
5
- "action": "create-new-lineage",
6
- "reason": "current repository target no longer matches the reviewed scope",
7
- "context": {
8
- "gate": "post-apply",
9
- "lineage_id": "issue136-contract-runtime",
10
- "generation": 1,
11
- "store_revision": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
12
- "genesis_revision": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
13
- "chain_identity": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
14
- "bundle_digest": "sha256:521b6a12b67ed75dd68b9ddb5543822c88da97a88e7257fd780b37dbedc35f8c",
15
- "base_tree": "cb234a1435871ed095db961750b8bb944fadbd43",
16
- "candidate_tree": "115773e92c079a714c37dad42ff672cdcc715d8c",
17
- "paths_digest": "sha256:0cc3964e29bb296c5f17bc496325961ed0df989b5333ac20d05770776a34be52",
18
- "fix_delta_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
19
- "policy_hash": "sha256:34fb63d7f29f8613cd4431382b1057398a4816f8a4c20fc34677fffc80a184f6",
20
- "ledger_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
21
- "evidence_hash": "sha256:2fa17828f842a4043ff7be11e4f439f40c6b06e1275538b6b4c800a27446f9d9",
22
- "base_relationship_valid": true,
23
- "denial": {
24
- "stage": "receipt-binding",
25
- "code": "candidate-or-paths-mismatch"
26
- }
27
- }
28
- }
@@ -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
- });