@pi-in-go/pigpen-jev 0.1.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 (128) hide show
  1. package/CREDITS.md +22 -0
  2. package/LICENSE +22 -0
  3. package/README.md +237 -0
  4. package/extensions/jev/ask.go +166 -0
  5. package/extensions/jev/ask_test.go +218 -0
  6. package/extensions/jev/backend.go +128 -0
  7. package/extensions/jev/bench_test.go +64 -0
  8. package/extensions/jev/boundaries_test.go +159 -0
  9. package/extensions/jev/command.go +224 -0
  10. package/extensions/jev/commands_test.go +214 -0
  11. package/extensions/jev/config.go +450 -0
  12. package/extensions/jev/errors_test.go +191 -0
  13. package/extensions/jev/extension.go +391 -0
  14. package/extensions/jev/fakehost_test.go +548 -0
  15. package/extensions/jev/gate.go +125 -0
  16. package/extensions/jev/gate_test.go +610 -0
  17. package/extensions/jev/gatekey_test.go +24 -0
  18. package/extensions/jev/go.mod +9 -0
  19. package/extensions/jev/go.sum +2 -0
  20. package/extensions/jev/go.work +10 -0
  21. package/extensions/jev/helpers_test.go +404 -0
  22. package/extensions/jev/memo.go +88 -0
  23. package/extensions/jev/output.go +89 -0
  24. package/extensions/jev/output_test.go +187 -0
  25. package/extensions/jev/ownmodel_test.go +118 -0
  26. package/extensions/jev/render.go +136 -0
  27. package/extensions/jev/review_test.go +310 -0
  28. package/extensions/jev/source_test.go +57 -0
  29. package/extensions/jev/text.go +174 -0
  30. package/extensions/jev/trust_test.go +335 -0
  31. package/extensions/jev/types.go +227 -0
  32. package/libs/typesafe/CONTRACT.md +125 -0
  33. package/libs/typesafe/CREDITS.md +37 -0
  34. package/libs/typesafe/LICENSE +23 -0
  35. package/libs/typesafe/README.md +19 -0
  36. package/libs/typesafe/go.mod +3 -0
  37. package/libs/typesafe/libraries/ownmodel/backend_test.go +496 -0
  38. package/libs/typesafe/libraries/ownmodel/canon.go +190 -0
  39. package/libs/typesafe/libraries/ownmodel/convert.go +199 -0
  40. package/libs/typesafe/libraries/ownmodel/doc.go +15 -0
  41. package/libs/typesafe/libraries/ownmodel/equivalence_test.go +199 -0
  42. package/libs/typesafe/libraries/ownmodel/helpers_test.go +155 -0
  43. package/libs/typesafe/libraries/ownmodel/mutation_test.go +31 -0
  44. package/libs/typesafe/libraries/ownmodel/ownmodel.go +225 -0
  45. package/libs/typesafe/libraries/ownmodel/plan.go +442 -0
  46. package/libs/typesafe/libraries/ownmodel/run.go +288 -0
  47. package/libs/typesafe/libraries/ownmodel/schema_test.go +254 -0
  48. package/libs/typesafe/libraries/ownmodel/twins_test.go +169 -0
  49. package/libs/typesafe/libraries/ownmodel/utils_test.go +125 -0
  50. package/libs/typesafe/libraries/pigmodel/pigmodel.go +264 -0
  51. package/libs/typesafe/libraries/pigmodel/pigmodel_test.go +410 -0
  52. package/libs/typesafe/libraries/typesafe/answers.go +268 -0
  53. package/libs/typesafe/libraries/typesafe/api_response_test.go +113 -0
  54. package/libs/typesafe/libraries/typesafe/batch.go +80 -0
  55. package/libs/typesafe/libraries/typesafe/batch_test.go +133 -0
  56. package/libs/typesafe/libraries/typesafe/bench_test.go +71 -0
  57. package/libs/typesafe/libraries/typesafe/client.go +561 -0
  58. package/libs/typesafe/libraries/typesafe/client_test.go +495 -0
  59. package/libs/typesafe/libraries/typesafe/crosscheck_test.go +464 -0
  60. package/libs/typesafe/libraries/typesafe/crosscheck_workflowevals_test.go +219 -0
  61. package/libs/typesafe/libraries/typesafe/doc.go +27 -0
  62. package/libs/typesafe/libraries/typesafe/entry.go +142 -0
  63. package/libs/typesafe/libraries/typesafe/env.go +11 -0
  64. package/libs/typesafe/libraries/typesafe/errors.go +310 -0
  65. package/libs/typesafe/libraries/typesafe/errors_test.go +175 -0
  66. package/libs/typesafe/libraries/typesafe/helpers_test.go +294 -0
  67. package/libs/typesafe/libraries/typesafe/live_test.go +96 -0
  68. package/libs/typesafe/libraries/typesafe/logging.go +160 -0
  69. package/libs/typesafe/libraries/typesafe/logging_test.go +259 -0
  70. package/libs/typesafe/libraries/typesafe/marshal_test.go +112 -0
  71. package/libs/typesafe/libraries/typesafe/mutation_test.go +39 -0
  72. package/libs/typesafe/libraries/typesafe/questions.go +490 -0
  73. package/libs/typesafe/libraries/typesafe/questions_test.go +166 -0
  74. package/libs/typesafe/libraries/typesafe/regressions_test.go +159 -0
  75. package/libs/typesafe/libraries/typesafe/reliability_test.go +649 -0
  76. package/libs/typesafe/libraries/typesafe/retry.go +350 -0
  77. package/libs/typesafe/libraries/typesafe/retry_test.go +297 -0
  78. package/libs/typesafe/libraries/typesafe/runtime_test.go +26 -0
  79. package/libs/typesafe/libraries/typesafe/transport_test.go +163 -0
  80. package/libs/typesafe/libraries/typesafe/twins_test.go +127 -0
  81. package/libs/typesafe/libraries/typesafe/types_test.go +165 -0
  82. package/libs/typesafe/libraries/typesafe/version.go +10 -0
  83. package/libs/typesafe/package.json +37 -0
  84. package/libs/typesafe/provenance.json +49 -0
  85. package/package.json +42 -0
  86. package/port/PORT.md +107 -0
  87. package/port/e2e/gate-and-output.py +35 -0
  88. package/port/e2e/jev-ask.py +36 -0
  89. package/port/e2e/model-switch.py +44 -0
  90. package/port/e2e/off-by-default.py +34 -0
  91. package/port/gen-scenarios.py +103 -0
  92. package/port/golden/cache-identical-calls.jsonl +30 -0
  93. package/port/golden/clear.jsonl +22 -0
  94. package/port/golden/commands.jsonl +43 -0
  95. package/port/golden/enforce-accept.jsonl +23 -0
  96. package/port/golden/enforce-decline.jsonl +22 -0
  97. package/port/golden/jev-ask.jsonl +20 -0
  98. package/port/golden/output-advice.jsonl +23 -0
  99. package/port/golden/output-leak.jsonl +24 -0
  100. package/port/golden/output-low-confidence.jsonl +22 -0
  101. package/port/golden/shadow-flagged.jsonl +23 -0
  102. package/port/golden/unjudged-tools.jsonl +19 -0
  103. package/port/golden/write-elision.jsonl +21 -0
  104. package/port/mutate-unit.py +63 -0
  105. package/port/mutations.json +578 -0
  106. package/port/oracle/LICENSE +21 -0
  107. package/port/oracle/README.md +181 -0
  108. package/port/oracle/SHA256SUMS +8 -0
  109. package/port/oracle/package.json +43 -0
  110. package/port/oracle/src/client.ts +409 -0
  111. package/port/oracle/src/config.ts +363 -0
  112. package/port/oracle/src/gate.ts +229 -0
  113. package/port/oracle/src/index.ts +649 -0
  114. package/port/oracle/src/output.ts +163 -0
  115. package/port/red-run.log +309 -0
  116. package/port/scenarios/cache-identical-calls.json +71 -0
  117. package/port/scenarios/clear.json +61 -0
  118. package/port/scenarios/commands.json +119 -0
  119. package/port/scenarios/enforce-accept.json +66 -0
  120. package/port/scenarios/enforce-decline.json +57 -0
  121. package/port/scenarios/jev-ask.json +83 -0
  122. package/port/scenarios/output-advice.json +61 -0
  123. package/port/scenarios/output-leak.json +61 -0
  124. package/port/scenarios/output-low-confidence.json +61 -0
  125. package/port/scenarios/shadow-flagged.json +61 -0
  126. package/port/scenarios/unjudged-tools.json +55 -0
  127. package/port/scenarios/write-elision.json +53 -0
  128. package/provenance.json +18 -0
@@ -0,0 +1,578 @@
1
+ [
2
+ {
3
+ "name": "default-on",
4
+ "file": "extension.go",
5
+ "find": "x.on = l.Config.Enabled",
6
+ "replace": "x.on = true"
7
+ },
8
+ {
9
+ "name": "no-opt-in-return",
10
+ "file": "extension.go",
11
+ "find": "if !l.Config.Enabled {\n\t\treturn\n\t}",
12
+ "replace": "if false {\n\t\treturn\n\t}"
13
+ },
14
+ {
15
+ "name": "project-can-consent",
16
+ "file": "config.go",
17
+ "find": "if project {\n\t\t\tignored = append(ignored, k)\n\t\t\treturn false\n\t\t}",
18
+ "replace": "if false {\n\t\t\treturn false\n\t\t}"
19
+ },
20
+ {
21
+ "name": "project-widens-argument-chars",
22
+ "file": "config.go",
23
+ "find": "(!project || n < c.Gate.ArgumentChars)",
24
+ "replace": "true"
25
+ },
26
+ {
27
+ "name": "project-widens-output-chars",
28
+ "file": "config.go",
29
+ "find": "(!project || n < c.Output.OutputChars)",
30
+ "replace": "true"
31
+ },
32
+ {
33
+ "name": "project-widens-state-cap",
34
+ "file": "config.go",
35
+ "find": "(!project || n < c.MaxStateChars)",
36
+ "replace": "true"
37
+ },
38
+ {
39
+ "name": "project-widens-tools",
40
+ "file": "config.go",
41
+ "find": "if !project {\n\t\treturn names\n\t}",
42
+ "replace": "if true {\n\t\treturn names\n\t}"
43
+ },
44
+ {
45
+ "name": "env-key-ignored",
46
+ "file": "config.go",
47
+ "find": "os.Getenv(apiKeyEnv)",
48
+ "replace": "\"\""
49
+ },
50
+ {
51
+ "name": "remote-http-accepted",
52
+ "file": "config.go",
53
+ "find": "return ip != nil && ip.IsLoopback()",
54
+ "replace": "return ip != nil || host != \"\""
55
+ },
56
+ {
57
+ "name": "plain-http-anywhere",
58
+ "file": "config.go",
59
+ "find": "if loopback(u.Hostname()) {",
60
+ "replace": "if true {"
61
+ },
62
+ {
63
+ "name": "endpoint-suffix-kept",
64
+ "file": "backend.go",
65
+ "find": "strings.TrimSuffix(raw, \"/v1/systemone\")",
66
+ "replace": "raw"
67
+ },
68
+ {
69
+ "name": "no-endpoint-check",
70
+ "file": "backend.go",
71
+ "find": "if c.Endpoint == \"\" {",
72
+ "replace": "if false {"
73
+ },
74
+ {
75
+ "name": "destructive-exclusive",
76
+ "file": "gate.go",
77
+ "find": "v.Destructive >= t.Destructive",
78
+ "replace": "v.Destructive > t.Destructive"
79
+ },
80
+ {
81
+ "name": "exfiltration-exclusive",
82
+ "file": "gate.go",
83
+ "find": "v.Exfiltration >= t.Exfiltration",
84
+ "replace": "v.Exfiltration > t.Exfiltration"
85
+ },
86
+ {
87
+ "name": "beyond-scope-exclusive",
88
+ "file": "gate.go",
89
+ "find": "v.BeyondScope >= t.BeyondScope",
90
+ "replace": "v.BeyondScope > t.BeyondScope"
91
+ },
92
+ {
93
+ "name": "impact-exclusive",
94
+ "file": "gate.go",
95
+ "find": "v.Impact >= t.Impact &&",
96
+ "replace": "v.Impact > t.Impact &&"
97
+ },
98
+ {
99
+ "name": "impact-confidence-exclusive",
100
+ "file": "gate.go",
101
+ "find": "imp.Confidence >= c.Gate.MinConfidence",
102
+ "replace": "imp.Confidence > c.Gate.MinConfidence"
103
+ },
104
+ {
105
+ "name": "impact-ignores-confidence",
106
+ "file": "gate.go",
107
+ "find": "(!imp.HasConfidence || imp.Confidence >= c.Gate.MinConfidence)",
108
+ "replace": "true"
109
+ },
110
+ {
111
+ "name": "state-cap-dropped",
112
+ "file": "gate.go",
113
+ "find": "for utf16Len(string(out)) > maxState && (argChars > 8 || userChars > 8) {",
114
+ "replace": "for false {"
115
+ },
116
+ {
117
+ "name": "user-request-1000",
118
+ "file": "gate.go",
119
+ "find": "const userRequestChars = 1200",
120
+ "replace": "const userRequestChars = 1000"
121
+ },
122
+ {
123
+ "name": "question-text-changed",
124
+ "file": "gate.go",
125
+ "find": "\"Is this action destructive?\"",
126
+ "replace": "\"Is this destructive?\""
127
+ },
128
+ {
129
+ "name": "reason-format",
130
+ "file": "gate.go",
131
+ "find": "s := fmt.Sprintf(\"impact %s/3\", toFixed2(v.Impact))",
132
+ "replace": "s := fmt.Sprintf(\"impact %s\", toFixed2(v.Impact))"
133
+ },
134
+ {
135
+ "name": "deep-strings-leak",
136
+ "file": "text.go",
137
+ "find": "if depth > maxNesting {\n\t\treturn \"…[nested value elided]\"\n\t}",
138
+ "replace": "if depth > 4 {\n\t\treturn v\n\t}"
139
+ },
140
+ {
141
+ "name": "elide-count-total",
142
+ "file": "text.go",
143
+ "find": "total-max)",
144
+ "replace": "total)"
145
+ },
146
+ {
147
+ "name": "utf16-as-runes",
148
+ "file": "text.go",
149
+ "find": "if r >= 0x10000 {\n\t\t\tw = 2\n\t\t}",
150
+ "replace": "if r >= 0x10000 && false {\n\t\t\tw = 2\n\t\t}"
151
+ },
152
+ {
153
+ "name": "tofixed-ties-down",
154
+ "file": "text.go",
155
+ "find": "r.Add(r, big.NewRat(1, 2))",
156
+ "replace": "r.Add(r, big.NewRat(0, 2))"
157
+ },
158
+ {
159
+ "name": "elide-marker",
160
+ "file": "text.go",
161
+ "find": "\"%s…[%d chars elided]\"",
162
+ "replace": "\"%s...[%d chars elided]\""
163
+ },
164
+ {
165
+ "name": "cache-ignores-user-request",
166
+ "file": "extension.go",
167
+ "find": "h.Write([]byte(truncateText(user, userRequestChars)))",
168
+ "replace": ""
169
+ },
170
+ {
171
+ "name": "cache-window-zero",
172
+ "file": "extension.go",
173
+ "find": "time.Duration(s.cfg.Gate.CacheSeconds)*time.Second",
174
+ "replace": "0"
175
+ },
176
+ {
177
+ "name": "output-cache-by-time",
178
+ "file": "extension.go",
179
+ "find": "key := tool + \"\\x00\" + out",
180
+ "replace": "key := tool + \"\\x00\" + out + time.Now().String()"
181
+ },
182
+ {
183
+ "name": "status-stays-clear-on-error",
184
+ "file": "extension.go",
185
+ "find": "x.setStatus(ctx, \"✗\", \"unavailable (failing open)\")",
186
+ "replace": ""
187
+ },
188
+ {
189
+ "name": "error-every-time",
190
+ "file": "extension.go",
191
+ "find": "quiet := x.now().Sub(x.lastErrorAt) < errorNotifyInterval",
192
+ "replace": "quiet := false"
193
+ },
194
+ {
195
+ "name": "fail-closed",
196
+ "file": "extension.go",
197
+ "find": "x.failOpen(ctx, err)\n\t\treturn nil, nil\n\t}\n\tv := evaluateGate",
198
+ "replace": "x.failOpen(ctx, err)\n\t\treturn map[string]any{\"block\": true, \"reason\": \"unavailable\"}, nil\n\t}\n\tv := evaluateGate"
199
+ },
200
+ {
201
+ "name": "shadow-blocks",
202
+ "file": "extension.go",
203
+ "find": "ctx.Notify(x.shadowNote(tool, v, s.cfg), \"warning\")\n\t\treturn nil, nil",
204
+ "replace": "ctx.Notify(x.shadowNote(tool, v, s.cfg), \"warning\")\n\t\treturn map[string]any{\"block\": true, \"reason\": reason}, nil"
205
+ },
206
+ {
207
+ "name": "headless-blocks-by-default",
208
+ "file": "extension.go",
209
+ "find": "if s.cfg.Gate.BlockWithoutUI {",
210
+ "replace": "if true {"
211
+ },
212
+ {
213
+ "name": "headless-asks",
214
+ "file": "extension.go",
215
+ "find": "if !ctx.HasUI() {",
216
+ "replace": "if false {"
217
+ },
218
+ {
219
+ "name": "decline-reason",
220
+ "file": "extension.go",
221
+ "find": "reason + \" (declined)\"",
222
+ "replace": "reason"
223
+ },
224
+ {
225
+ "name": "gate-judges-every-tool",
226
+ "file": "extension.go",
227
+ "find": "|| !slices.Contains(s.cfg.Gate.Tools, tool) {",
228
+ "replace": "{"
229
+ },
230
+ {
231
+ "name": "output-judges-every-tool",
232
+ "file": "extension.go",
233
+ "find": "|| !slices.Contains(s.cfg.Output.Tools, tool) {",
234
+ "replace": "{"
235
+ },
236
+ {
237
+ "name": "output-judges-empty",
238
+ "file": "extension.go",
239
+ "find": "if strings.TrimSpace(out) == \"\" {",
240
+ "replace": "if false {"
241
+ },
242
+ {
243
+ "name": "output-blocks-joined",
244
+ "file": "extension.go",
245
+ "find": "strings.Join(parts, \"\\n\")",
246
+ "replace": "strings.Join(parts, \"\")"
247
+ },
248
+ {
249
+ "name": "notice-prefix",
250
+ "file": "extension.go",
251
+ "find": "\"[pi-jev] \" + v.Notice",
252
+ "replace": "v.Notice"
253
+ },
254
+ {
255
+ "name": "leak-not-notified",
256
+ "file": "extension.go",
257
+ "find": "ctx.Notify(x.leakNote(tool, v.LeaksSecret, s.cfg), \"warning\")",
258
+ "replace": ""
259
+ },
260
+ {
261
+ "name": "user-request-untrimmed",
262
+ "file": "extension.go",
263
+ "find": "if t := strings.TrimSpace(branch[i].Content); t != \"\" {",
264
+ "replace": "if t := branch[i].Content; t != \"\" {"
265
+ },
266
+ {
267
+ "name": "user-request-first",
268
+ "file": "extension.go",
269
+ "find": "for i := len(branch) - 1; i >= 0; i-- {",
270
+ "replace": "for i := 0; i < len(branch); i++ {"
271
+ },
272
+ {
273
+ "name": "leak-exclusive",
274
+ "file": "output.go",
275
+ "find": "v.LeaksSecret >= c.Output.LeakThreshold",
276
+ "replace": "v.LeaksSecret > c.Output.LeakThreshold"
277
+ },
278
+ {
279
+ "name": "class-confidence-exclusive",
280
+ "file": "output.go",
281
+ "find": "v.ClassConfidence >= c.Output.MinConfidence",
282
+ "replace": "v.ClassConfidence > c.Output.MinConfidence"
283
+ },
284
+ {
285
+ "name": "no-failure-advice",
286
+ "file": "output.go",
287
+ "find": "classAdvice[v.FailureClass] != \"\" &&",
288
+ "replace": "true &&"
289
+ },
290
+ {
291
+ "name": "advice-text",
292
+ "file": "output.go",
293
+ "find": "\"retrying the same command unchanged is reasonable\"",
294
+ "replace": "\"retry\""
295
+ },
296
+ {
297
+ "name": "advice-sentence",
298
+ "file": "output.go",
299
+ "find": "(confidence %s): %s.\"",
300
+ "replace": "(confidence %s): %s\""
301
+ },
302
+ {
303
+ "name": "leak-text",
304
+ "file": "output.go",
305
+ "find": "refer to it by name instead.",
306
+ "replace": "refer to it by name."
307
+ },
308
+ {
309
+ "name": "noul-range-unchecked",
310
+ "file": "types.go",
311
+ "find": "if !inRatio(t.Noul) {",
312
+ "replace": "if false {"
313
+ },
314
+ {
315
+ "name": "answer-type-unchecked",
316
+ "file": "types.go",
317
+ "find": "string(raw.AnswerType()) != q.Type",
318
+ "replace": "false"
319
+ },
320
+ {
321
+ "name": "missing-answer-unchecked",
322
+ "file": "types.go",
323
+ "find": "if !present {",
324
+ "replace": "if !present && false {"
325
+ },
326
+ {
327
+ "name": "choice-any-option",
328
+ "file": "types.go",
329
+ "find": "found = found || o.Name == t.Choice",
330
+ "replace": "found = found || o.Name == t.Choice || true"
331
+ },
332
+ {
333
+ "name": "score-range-unchecked",
334
+ "file": "types.go",
335
+ "find": "t.Score > float64(len(q.Levels)-1)",
336
+ "replace": "false"
337
+ },
338
+ {
339
+ "name": "choice-confidence-unchecked",
340
+ "file": "types.go",
341
+ "find": "case typesafe.ChoiceAnswer:\n\t\tif !inRatio(t.Confidence) {",
342
+ "replace": "case typesafe.ChoiceAnswer:\n\t\tif false {"
343
+ },
344
+ {
345
+ "name": "score-legend-levels",
346
+ "file": "types.go",
347
+ "find": "levels := len(a.Legend) - 1",
348
+ "replace": "levels := len(a.Legend)"
349
+ },
350
+ {
351
+ "name": "choice-order",
352
+ "file": "types.go",
353
+ "find": "ranked[i].Value > ranked[j].Value",
354
+ "replace": "ranked[i].Value < ranked[j].Value"
355
+ },
356
+ {
357
+ "name": "duplicate-ids-allowed",
358
+ "file": "types.go",
359
+ "find": "if seen[q.ID] {",
360
+ "replace": "if false {"
361
+ },
362
+ {
363
+ "name": "blank-instructions-allowed",
364
+ "file": "types.go",
365
+ "find": "if strings.TrimSpace(q.Instructions) == \"\" {",
366
+ "replace": "if false {"
367
+ },
368
+ {
369
+ "name": "no-inflight-sharing",
370
+ "file": "memo.go",
371
+ "find": "if f, ok := m.flights[key]; ok {",
372
+ "replace": "if f, ok := m.flights[key]; ok && false {"
373
+ },
374
+ {
375
+ "name": "errors-cached",
376
+ "file": "memo.go",
377
+ "find": "if f.err == nil && ttl > 0 {",
378
+ "replace": "if ttl > 0 {"
379
+ },
380
+ {
381
+ "name": "cache-unbounded",
382
+ "file": "memo.go",
383
+ "find": "const memoLimit = 64",
384
+ "replace": "const memoLimit = 1 << 20"
385
+ },
386
+ {
387
+ "name": "cache-never-expires",
388
+ "file": "memo.go",
389
+ "find": "ttl > 0 && now().Sub(e.at) <= ttl",
390
+ "replace": "ttl > 0"
391
+ },
392
+ {
393
+ "name": "off-keeps-ask",
394
+ "file": "command.go",
395
+ "find": "x.on, x.gateOn, x.outputOn = false, false, false",
396
+ "replace": "x.gateOn, x.outputOn = false, false"
397
+ },
398
+ {
399
+ "name": "on-without-consent",
400
+ "file": "command.go",
401
+ "find": "if !s.cfg.Enabled && !s.on {",
402
+ "replace": "if false {"
403
+ },
404
+ {
405
+ "name": "check-while-off",
406
+ "file": "command.go",
407
+ "find": "if s.be == nil || !s.on {",
408
+ "replace": "if s.be == nil {"
409
+ },
410
+ {
411
+ "name": "mode-accepts-anything",
412
+ "file": "command.go",
413
+ "find": "if value != \"shadow\" && value != \"enforce\" {",
414
+ "replace": "if false {"
415
+ },
416
+ {
417
+ "name": "output-verdict-kind",
418
+ "file": "command.go",
419
+ "find": "%s - %s | leak %s | class %s at %s\"",
420
+ "replace": "%s %s | leak %s | class %s at %s\""
421
+ },
422
+ {
423
+ "name": "status-key-source",
424
+ "file": "command.go",
425
+ "find": "keySource = \"missing (\" + apiKeyEnv + \")\"",
426
+ "replace": "keySource = \"apiKey (inline)\""
427
+ },
428
+ {
429
+ "name": "shadow-wording",
430
+ "file": "render.go",
431
+ "find": "\"jev shadow: %s - %s\"",
432
+ "replace": "\"jev shadow: %s: %s\""
433
+ },
434
+ {
435
+ "name": "confirm-plain",
436
+ "file": "render.go",
437
+ "find": "\"%s\\n%s\\n\\nRun it anyway?\"",
438
+ "replace": "\"%s %s\\n\\nRun it anyway?\""
439
+ },
440
+ {
441
+ "name": "headless-wording",
442
+ "file": "render.go",
443
+ "find": "tail := \"(headless: not blocking; set gate.blockWithoutUI to block)\"",
444
+ "replace": "tail := \"(headless)\""
445
+ },
446
+ {
447
+ "name": "status-plain",
448
+ "file": "render.go",
449
+ "find": "return \"jev: \" + rest",
450
+ "replace": "return \"jev \" + rest"
451
+ },
452
+ {
453
+ "name": "leak-note-plain",
454
+ "file": "render.go",
455
+ "find": "\"jev: %s output may carry a secret (%s)\"",
456
+ "replace": "\"jev: %s output may carry a secret %s\""
457
+ },
458
+ {
459
+ "name": "failure-note-plain",
460
+ "file": "render.go",
461
+ "find": "\"pi-jev: %s (failing open)\"",
462
+ "replace": "\"pi-jev: %s\""
463
+ },
464
+ {
465
+ "name": "disclosure-omits-destination",
466
+ "file": "render.go",
467
+ "find": "fmt.Fprintf(&b, \"Destination: %s\\n\", dest)",
468
+ "replace": ""
469
+ },
470
+ {
471
+ "name": "disclosure-omits-fail-open",
472
+ "file": "render.go",
473
+ "find": "If the judge is unavailable, tool calls run unjudged (it fails open). ",
474
+ "replace": ""
475
+ },
476
+ {
477
+ "name": "ask-off-allowed",
478
+ "file": "ask.go",
479
+ "find": "if !s.on || s.be == nil {",
480
+ "replace": "if s.be == nil {"
481
+ },
482
+ {
483
+ "name": "ask-state-uncapped",
484
+ "file": "ask.go",
485
+ "find": "elide(state, s.cfg.MaxStateChars)",
486
+ "replace": "state"
487
+ },
488
+ {
489
+ "name": "review-confirm-failure-fails-open",
490
+ "file": "extension.go",
491
+ "find": "return map[string]any{\"block\": true, \"reason\": fmt.Sprintf(\"%s (not confirmed: %s)\", reason, x.redact(cerr.Error()))}, nil",
492
+ "replace": "return nil, nil"
493
+ },
494
+ {
495
+ "name": "review-model-select-ignored",
496
+ "file": "extension.go",
497
+ "find": "if cfg.Backend != backendModel || cfg.Model != \"\" {\n\t\treturn\n\t}\n\tbe, err := newBackend(cfg, ctx)",
498
+ "replace": "if true {\n\t\treturn\n\t}\n\tbe, err := newBackend(cfg, ctx)"
499
+ },
500
+ {
501
+ "name": "review-model-select-overrides-configured-model",
502
+ "file": "extension.go",
503
+ "find": "if cfg.Backend != backendModel || cfg.Model != \"\" {\n\t\treturn\n\t}\n\tbe, err := newBackend(cfg, ctx)",
504
+ "replace": "if cfg.Backend != backendModel {\n\t\treturn\n\t}\n\tcfg.Model = \"\"\n\tbe, err := newBackend(cfg, ctx)"
505
+ },
506
+ {
507
+ "name": "review-model-select-no-ask-registration",
508
+ "file": "extension.go",
509
+ "find": "\tx.baseStatus(ctx)\n\tx.registerAsk(ctx)\n\tctx.Notify(\"pi-jev: now judging with \"",
510
+ "replace": "\tx.baseStatus(ctx)\n\tctx.Notify(\"pi-jev: now judging with \""
511
+ },
512
+ {
513
+ "name": "review-disclosure-omits-jev-ask",
514
+ "file": "render.go",
515
+ "find": "fmt.Fprintf(&b, \"Also sent: text the model passes to jev_ask (up to %d characters) and text you pass to /jev check.\\n\", c.MaxStateChars)\n",
516
+ "replace": ""
517
+ },
518
+ {
519
+ "name": "review-relaxations-silent",
520
+ "file": "config.go",
521
+ "find": "if relaxed := relaxations(before, c); len(relaxed) > 0 {",
522
+ "replace": "if relaxed := relaxations(before, c); false && len(relaxed) > 0 {"
523
+ },
524
+ {
525
+ "name": "review-relaxation-mode-unreported",
526
+ "file": "config.go",
527
+ "find": "if user.Gate.Mode == \"enforce\" && merged.Gate.Mode != \"enforce\" {",
528
+ "replace": "if false {"
529
+ },
530
+ {
531
+ "name": "review-relaxation-threshold-direction",
532
+ "file": "config.go",
533
+ "find": "if t.is > t.was {",
534
+ "replace": "if t.is != t.was {"
535
+ },
536
+ {
537
+ "name": "review-project-keyfile",
538
+ "file": "config.go",
539
+ "find": "\tif key(\"apiKeyFile\") {",
540
+ "replace": "\tif _, ok := m[\"apiKeyFile\"]; ok {"
541
+ },
542
+ {
543
+ "name": "review-project-backend",
544
+ "file": "config.go",
545
+ "find": "\tif key(\"backend\") {",
546
+ "replace": "\tif _, ok := m[\"backend\"]; ok {"
547
+ },
548
+ {
549
+ "name": "review-project-model",
550
+ "file": "config.go",
551
+ "find": "\tif key(\"model\") {",
552
+ "replace": "\tif _, ok := m[\"model\"]; ok {"
553
+ },
554
+ {
555
+ "name": "review-project-ack",
556
+ "file": "config.go",
557
+ "find": "\tif key(\"acknowledged\") {",
558
+ "replace": "\tif _, ok := m[\"acknowledged\"]; ok {"
559
+ },
560
+ {
561
+ "name": "review-loopback-any",
562
+ "file": "config.go",
563
+ "find": "return ip != nil && ip.IsLoopback()",
564
+ "replace": "return ip != nil"
565
+ },
566
+ {
567
+ "name": "review-output-key-no-tool",
568
+ "file": "extension.go",
569
+ "find": "key := tool + \"\\x00\" + out",
570
+ "replace": "key := out"
571
+ },
572
+ {
573
+ "name": "review-drop-user-before-args",
574
+ "file": "gate.go",
575
+ "find": "\t\tout = build(argChars, userChars, true, false)\n",
576
+ "replace": "\t\tout = build(argChars, userChars, false, true)\n"
577
+ }
578
+ ]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 y0usaf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.