@openagentsy/hooks 0.0.0-stage → 0.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 (307) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +32 -2
  3. package/dist/accountability.d.ts +29 -0
  4. package/dist/accountability.d.ts.map +1 -0
  5. package/dist/accountability.js +21 -0
  6. package/dist/accountability.js.map +1 -0
  7. package/dist/accountability.test.d.ts +2 -0
  8. package/dist/accountability.test.d.ts.map +1 -0
  9. package/dist/accountability.test.js +42 -0
  10. package/dist/accountability.test.js.map +1 -0
  11. package/dist/approvals.d.ts +110 -0
  12. package/dist/approvals.d.ts.map +1 -0
  13. package/dist/approvals.js +464 -0
  14. package/dist/approvals.js.map +1 -0
  15. package/dist/approvals.test.d.ts +2 -0
  16. package/dist/approvals.test.d.ts.map +1 -0
  17. package/dist/approvals.test.js +307 -0
  18. package/dist/approvals.test.js.map +1 -0
  19. package/dist/base-tool.d.ts +26 -0
  20. package/dist/base-tool.d.ts.map +1 -0
  21. package/dist/base-tool.js +37 -0
  22. package/dist/base-tool.js.map +1 -0
  23. package/dist/base-tool.test.d.ts +2 -0
  24. package/dist/base-tool.test.d.ts.map +1 -0
  25. package/dist/base-tool.test.js +34 -0
  26. package/dist/base-tool.test.js.map +1 -0
  27. package/dist/eval/index.d.ts +3 -0
  28. package/dist/eval/index.d.ts.map +1 -0
  29. package/dist/eval/index.js +3 -0
  30. package/dist/eval/index.js.map +1 -0
  31. package/dist/eval/runner.d.ts +179 -0
  32. package/dist/eval/runner.d.ts.map +1 -0
  33. package/dist/eval/runner.js +616 -0
  34. package/dist/eval/runner.js.map +1 -0
  35. package/dist/eval/runner.test.d.ts +2 -0
  36. package/dist/eval/runner.test.d.ts.map +1 -0
  37. package/dist/eval/runner.test.js +431 -0
  38. package/dist/eval/runner.test.js.map +1 -0
  39. package/dist/eval/types.d.ts +173 -0
  40. package/dist/eval/types.d.ts.map +1 -0
  41. package/dist/eval/types.js +104 -0
  42. package/dist/eval/types.js.map +1 -0
  43. package/dist/event.d.ts +59 -0
  44. package/dist/event.d.ts.map +1 -0
  45. package/dist/event.js +178 -0
  46. package/dist/event.js.map +1 -0
  47. package/dist/event.test.d.ts +2 -0
  48. package/dist/event.test.d.ts.map +1 -0
  49. package/dist/event.test.js +49 -0
  50. package/dist/event.test.js.map +1 -0
  51. package/dist/index.d.ts +30 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +29 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/lessons/capture.d.ts +66 -0
  56. package/dist/lessons/capture.d.ts.map +1 -0
  57. package/dist/lessons/capture.js +166 -0
  58. package/dist/lessons/capture.js.map +1 -0
  59. package/dist/lessons/capture.test.d.ts +2 -0
  60. package/dist/lessons/capture.test.d.ts.map +1 -0
  61. package/dist/lessons/capture.test.js +200 -0
  62. package/dist/lessons/capture.test.js.map +1 -0
  63. package/dist/lessons/decide.d.ts +90 -0
  64. package/dist/lessons/decide.d.ts.map +1 -0
  65. package/dist/lessons/decide.js +334 -0
  66. package/dist/lessons/decide.js.map +1 -0
  67. package/dist/lessons/decide.test.d.ts +2 -0
  68. package/dist/lessons/decide.test.d.ts.map +1 -0
  69. package/dist/lessons/decide.test.js +527 -0
  70. package/dist/lessons/decide.test.js.map +1 -0
  71. package/dist/lessons/id.d.ts +5 -0
  72. package/dist/lessons/id.d.ts.map +1 -0
  73. package/dist/lessons/id.js +20 -0
  74. package/dist/lessons/id.js.map +1 -0
  75. package/dist/lessons/index.d.ts +5 -0
  76. package/dist/lessons/index.d.ts.map +1 -0
  77. package/dist/lessons/index.js +5 -0
  78. package/dist/lessons/index.js.map +1 -0
  79. package/dist/lessons/model.d.ts +163 -0
  80. package/dist/lessons/model.d.ts.map +1 -0
  81. package/dist/lessons/model.js +181 -0
  82. package/dist/lessons/model.js.map +1 -0
  83. package/dist/lessons/model.test.d.ts +2 -0
  84. package/dist/lessons/model.test.d.ts.map +1 -0
  85. package/dist/lessons/model.test.js +178 -0
  86. package/dist/lessons/model.test.js.map +1 -0
  87. package/dist/lessons/permissions.test.d.ts +2 -0
  88. package/dist/lessons/permissions.test.d.ts.map +1 -0
  89. package/dist/lessons/permissions.test.js +88 -0
  90. package/dist/lessons/permissions.test.js.map +1 -0
  91. package/dist/lessons/store.d.ts +74 -0
  92. package/dist/lessons/store.d.ts.map +1 -0
  93. package/dist/lessons/store.js +231 -0
  94. package/dist/lessons/store.js.map +1 -0
  95. package/dist/output-checks.d.ts +64 -0
  96. package/dist/output-checks.d.ts.map +1 -0
  97. package/dist/output-checks.js +248 -0
  98. package/dist/output-checks.js.map +1 -0
  99. package/dist/output-checks.test.d.ts +2 -0
  100. package/dist/output-checks.test.d.ts.map +1 -0
  101. package/dist/output-checks.test.js +58 -0
  102. package/dist/output-checks.test.js.map +1 -0
  103. package/dist/paths.d.ts +37 -0
  104. package/dist/paths.d.ts.map +1 -0
  105. package/dist/paths.js +70 -0
  106. package/dist/paths.js.map +1 -0
  107. package/dist/paths.test.d.ts +2 -0
  108. package/dist/paths.test.d.ts.map +1 -0
  109. package/dist/paths.test.js +36 -0
  110. package/dist/paths.test.js.map +1 -0
  111. package/dist/policies/agi-framing.d.ts +12 -0
  112. package/dist/policies/agi-framing.d.ts.map +1 -0
  113. package/dist/policies/agi-framing.js +33 -0
  114. package/dist/policies/agi-framing.js.map +1 -0
  115. package/dist/policies/anti-anthropomorphism.d.ts +13 -0
  116. package/dist/policies/anti-anthropomorphism.d.ts.map +1 -0
  117. package/dist/policies/anti-anthropomorphism.js +34 -0
  118. package/dist/policies/anti-anthropomorphism.js.map +1 -0
  119. package/dist/policies/anti-dependence.d.ts +12 -0
  120. package/dist/policies/anti-dependence.d.ts.map +1 -0
  121. package/dist/policies/anti-dependence.js +33 -0
  122. package/dist/policies/anti-dependence.js.map +1 -0
  123. package/dist/policies/anti-sycophancy.d.ts +13 -0
  124. package/dist/policies/anti-sycophancy.d.ts.map +1 -0
  125. package/dist/policies/anti-sycophancy.js +34 -0
  126. package/dist/policies/anti-sycophancy.js.map +1 -0
  127. package/dist/policies/dark-pattern.d.ts +14 -0
  128. package/dist/policies/dark-pattern.d.ts.map +1 -0
  129. package/dist/policies/dark-pattern.js +44 -0
  130. package/dist/policies/dark-pattern.js.map +1 -0
  131. package/dist/policies/destructive-needs-approval.d.ts +14 -0
  132. package/dist/policies/destructive-needs-approval.d.ts.map +1 -0
  133. package/dist/policies/destructive-needs-approval.js +31 -0
  134. package/dist/policies/destructive-needs-approval.js.map +1 -0
  135. package/dist/policies/discovery.d.ts +12 -0
  136. package/dist/policies/discovery.d.ts.map +1 -0
  137. package/dist/policies/discovery.js +130 -0
  138. package/dist/policies/discovery.js.map +1 -0
  139. package/dist/policies/high-risk.d.ts +25 -0
  140. package/dist/policies/high-risk.d.ts.map +1 -0
  141. package/dist/policies/high-risk.js +105 -0
  142. package/dist/policies/high-risk.js.map +1 -0
  143. package/dist/policies/human-only-decisions.d.ts +14 -0
  144. package/dist/policies/human-only-decisions.d.ts.map +1 -0
  145. package/dist/policies/human-only-decisions.js +33 -0
  146. package/dist/policies/human-only-decisions.js.map +1 -0
  147. package/dist/policies/index.d.ts +29 -0
  148. package/dist/policies/index.d.ts.map +1 -0
  149. package/dist/policies/index.js +82 -0
  150. package/dist/policies/index.js.map +1 -0
  151. package/dist/policies/no-skip-git-hooks.d.ts +14 -0
  152. package/dist/policies/no-skip-git-hooks.d.ts.map +1 -0
  153. package/dist/policies/no-skip-git-hooks.js +31 -0
  154. package/dist/policies/no-skip-git-hooks.js.map +1 -0
  155. package/dist/policies/package-manager.d.ts +12 -0
  156. package/dist/policies/package-manager.d.ts.map +1 -0
  157. package/dist/policies/package-manager.js +29 -0
  158. package/dist/policies/package-manager.js.map +1 -0
  159. package/dist/policies/patterns.d.ts +17 -0
  160. package/dist/policies/patterns.d.ts.map +1 -0
  161. package/dist/policies/patterns.js +30 -0
  162. package/dist/policies/patterns.js.map +1 -0
  163. package/dist/policies/policies.test.d.ts +2 -0
  164. package/dist/policies/policies.test.d.ts.map +1 -0
  165. package/dist/policies/policies.test.js +210 -0
  166. package/dist/policies/policies.test.js.map +1 -0
  167. package/dist/policies/privacy-transparency.d.ts +14 -0
  168. package/dist/policies/privacy-transparency.d.ts.map +1 -0
  169. package/dist/policies/privacy-transparency.js +50 -0
  170. package/dist/policies/privacy-transparency.js.map +1 -0
  171. package/dist/policies/professional-displacement.d.ts +15 -0
  172. package/dist/policies/professional-displacement.d.ts.map +1 -0
  173. package/dist/policies/professional-displacement.js +45 -0
  174. package/dist/policies/professional-displacement.js.map +1 -0
  175. package/dist/policies/protect-policy.d.ts +14 -0
  176. package/dist/policies/protect-policy.d.ts.map +1 -0
  177. package/dist/policies/protect-policy.js +35 -0
  178. package/dist/policies/protect-policy.js.map +1 -0
  179. package/dist/policies/scope-enforcement.d.ts +14 -0
  180. package/dist/policies/scope-enforcement.d.ts.map +1 -0
  181. package/dist/policies/scope-enforcement.js +34 -0
  182. package/dist/policies/scope-enforcement.js.map +1 -0
  183. package/dist/policies/secret-scan-writes.d.ts +13 -0
  184. package/dist/policies/secret-scan-writes.d.ts.map +1 -0
  185. package/dist/policies/secret-scan-writes.js +38 -0
  186. package/dist/policies/secret-scan-writes.js.map +1 -0
  187. package/dist/policies/selection.d.ts +20 -0
  188. package/dist/policies/selection.d.ts.map +1 -0
  189. package/dist/policies/selection.js +93 -0
  190. package/dist/policies/selection.js.map +1 -0
  191. package/dist/policies/structural-bias.d.ts +14 -0
  192. package/dist/policies/structural-bias.d.ts.map +1 -0
  193. package/dist/policies/structural-bias.js +41 -0
  194. package/dist/policies/structural-bias.js.map +1 -0
  195. package/dist/policies/third-party-impact.d.ts +13 -0
  196. package/dist/policies/third-party-impact.d.ts.map +1 -0
  197. package/dist/policies/third-party-impact.js +38 -0
  198. package/dist/policies/third-party-impact.js.map +1 -0
  199. package/dist/policies/tool-call.d.ts +38 -0
  200. package/dist/policies/tool-call.d.ts.map +1 -0
  201. package/dist/policies/tool-call.js +53 -0
  202. package/dist/policies/tool-call.js.map +1 -0
  203. package/dist/policies/truthfulness-uncertainty.d.ts +13 -0
  204. package/dist/policies/truthfulness-uncertainty.d.ts.map +1 -0
  205. package/dist/policies/truthfulness-uncertainty.js +45 -0
  206. package/dist/policies/truthfulness-uncertainty.js.map +1 -0
  207. package/dist/policies/workspace-writes-only.d.ts +25 -0
  208. package/dist/policies/workspace-writes-only.d.ts.map +1 -0
  209. package/dist/policies/workspace-writes-only.js +54 -0
  210. package/dist/policies/workspace-writes-only.js.map +1 -0
  211. package/dist/policy-engine.d.ts +69 -0
  212. package/dist/policy-engine.d.ts.map +1 -0
  213. package/dist/policy-engine.js +145 -0
  214. package/dist/policy-engine.js.map +1 -0
  215. package/dist/policy-registry.d.ts +62 -0
  216. package/dist/policy-registry.d.ts.map +1 -0
  217. package/dist/policy-registry.js +63 -0
  218. package/dist/policy-registry.js.map +1 -0
  219. package/dist/policy-registry.test.d.ts +2 -0
  220. package/dist/policy-registry.test.d.ts.map +1 -0
  221. package/dist/policy-registry.test.js +79 -0
  222. package/dist/policy-registry.test.js.map +1 -0
  223. package/dist/policy-release.d.ts +44 -0
  224. package/dist/policy-release.d.ts.map +1 -0
  225. package/dist/policy-release.js +65 -0
  226. package/dist/policy-release.js.map +1 -0
  227. package/dist/policy.d.ts +141 -0
  228. package/dist/policy.d.ts.map +1 -0
  229. package/dist/policy.js +22 -0
  230. package/dist/policy.js.map +1 -0
  231. package/dist/quality/audit.d.ts +56 -0
  232. package/dist/quality/audit.d.ts.map +1 -0
  233. package/dist/quality/audit.js +52 -0
  234. package/dist/quality/audit.js.map +1 -0
  235. package/dist/quality/findings.d.ts +34 -0
  236. package/dist/quality/findings.d.ts.map +1 -0
  237. package/dist/quality/findings.js +121 -0
  238. package/dist/quality/findings.js.map +1 -0
  239. package/dist/quality/findings.test.d.ts +2 -0
  240. package/dist/quality/findings.test.d.ts.map +1 -0
  241. package/dist/quality/findings.test.js +79 -0
  242. package/dist/quality/findings.test.js.map +1 -0
  243. package/dist/quality/index.d.ts +20 -0
  244. package/dist/quality/index.d.ts.map +1 -0
  245. package/dist/quality/index.js +20 -0
  246. package/dist/quality/index.js.map +1 -0
  247. package/dist/quality/rule.d.ts +43 -0
  248. package/dist/quality/rule.d.ts.map +1 -0
  249. package/dist/quality/rule.js +162 -0
  250. package/dist/quality/rule.js.map +1 -0
  251. package/dist/quality/rule.test.d.ts +2 -0
  252. package/dist/quality/rule.test.d.ts.map +1 -0
  253. package/dist/quality/rule.test.js +187 -0
  254. package/dist/quality/rule.test.js.map +1 -0
  255. package/dist/quality/tools.d.ts +30 -0
  256. package/dist/quality/tools.d.ts.map +1 -0
  257. package/dist/quality/tools.js +33 -0
  258. package/dist/quality/tools.js.map +1 -0
  259. package/dist/quality/tools.test.d.ts +2 -0
  260. package/dist/quality/tools.test.d.ts.map +1 -0
  261. package/dist/quality/tools.test.js +41 -0
  262. package/dist/quality/tools.test.js.map +1 -0
  263. package/dist/quality/waive.d.ts +37 -0
  264. package/dist/quality/waive.d.ts.map +1 -0
  265. package/dist/quality/waive.js +39 -0
  266. package/dist/quality/waive.js.map +1 -0
  267. package/dist/quality/waivers.d.ts +63 -0
  268. package/dist/quality/waivers.d.ts.map +1 -0
  269. package/dist/quality/waivers.js +132 -0
  270. package/dist/quality/waivers.js.map +1 -0
  271. package/dist/quality/waivers.test.d.ts +2 -0
  272. package/dist/quality/waivers.test.d.ts.map +1 -0
  273. package/dist/quality/waivers.test.js +138 -0
  274. package/dist/quality/waivers.test.js.map +1 -0
  275. package/dist/registry.d.ts +86 -0
  276. package/dist/registry.d.ts.map +1 -0
  277. package/dist/registry.js +92 -0
  278. package/dist/registry.js.map +1 -0
  279. package/dist/registry.test.d.ts +2 -0
  280. package/dist/registry.test.d.ts.map +1 -0
  281. package/dist/registry.test.js +117 -0
  282. package/dist/registry.test.js.map +1 -0
  283. package/dist/rules.d.ts +107 -0
  284. package/dist/rules.d.ts.map +1 -0
  285. package/dist/rules.js +632 -0
  286. package/dist/rules.js.map +1 -0
  287. package/dist/rules.test.d.ts +2 -0
  288. package/dist/rules.test.d.ts.map +1 -0
  289. package/dist/rules.test.js +488 -0
  290. package/dist/rules.test.js.map +1 -0
  291. package/dist/secrets.d.ts +17 -0
  292. package/dist/secrets.d.ts.map +1 -0
  293. package/dist/secrets.js +17 -0
  294. package/dist/secrets.js.map +1 -0
  295. package/dist/secrets.test.d.ts +2 -0
  296. package/dist/secrets.test.d.ts.map +1 -0
  297. package/dist/secrets.test.js +20 -0
  298. package/dist/secrets.test.js.map +1 -0
  299. package/dist/shell-env.d.ts +23 -0
  300. package/dist/shell-env.d.ts.map +1 -0
  301. package/dist/shell-env.js +34 -0
  302. package/dist/shell-env.js.map +1 -0
  303. package/dist/shell-env.test.d.ts +2 -0
  304. package/dist/shell-env.test.d.ts.map +1 -0
  305. package/dist/shell-env.test.js +45 -0
  306. package/dist/shell-env.test.js.map +1 -0
  307. package/package.json +49 -4
@@ -0,0 +1,527 @@
1
+ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { hashOf } from '../eval/runner.js';
6
+ import { captureCandidate } from './capture.js';
7
+ import { decideLesson, proofPath } from './decide.js';
8
+ import { readLesson } from './store.js';
9
+ async function temporaryRoot() {
10
+ const root = await mkdtemp(join(tmpdir(), 'openagentsy-decide-'));
11
+ return { root, remove: () => rm(root, { recursive: true, force: true }) };
12
+ }
13
+ /** A packet that says everything it has to say. */
14
+ function completePacket(proof) {
15
+ return {
16
+ futureBehavior: 'read the file before writing to it',
17
+ representativeTask: 'the agent writes to a file that does not exist',
18
+ evidence: ['session-1'],
19
+ owner: 'test:missing-file',
20
+ writeBoundary: ['packages/hooks/src/**'],
21
+ proof,
22
+ };
23
+ }
24
+ /**
25
+ * A proof that passes, and the name of the file it is in.
26
+ *
27
+ * The proof is an artifact the runner can run, so the decision has a real
28
+ * verdict to rest on.
29
+ */
30
+ async function proofArtifact(root, lessonId, name = 'proof.json') {
31
+ const script = join(root, 'ok.js');
32
+ await writeFile(script, 'console.log("ok");\n', 'utf8');
33
+ await writeFile(join(root, name), JSON.stringify({
34
+ schema_version: '1',
35
+ lesson_id: lessonId,
36
+ name: 'the proof',
37
+ scenarios: [
38
+ {
39
+ id: 's',
40
+ phase: 'candidate',
41
+ cwd: '.',
42
+ command: [process.execPath, script],
43
+ expect: { stdout_includes: ['ok'] },
44
+ },
45
+ ],
46
+ }), 'utf8');
47
+ return name;
48
+ }
49
+ /** The hash of a proof file. */
50
+ async function proofHash(root, name) {
51
+ return hashOf(await readFile(join(root, name), 'utf8'));
52
+ }
53
+ /** A scenario, as a run records it. */
54
+ function scenario() {
55
+ return {
56
+ id: 's',
57
+ phase: 'candidate',
58
+ command_sha256: 'c'.repeat(64),
59
+ exit_code: 0,
60
+ timed_out: false,
61
+ duration_ms: 1,
62
+ assertions: { exit_code: true },
63
+ passed: true,
64
+ };
65
+ }
66
+ /** A result, built by hand. */
67
+ function result(lessonId, artifactSha, runs = 1, passed = true, withScenarios = false) {
68
+ return {
69
+ schema_version: '1',
70
+ lesson_id: lessonId,
71
+ artifact_sha256: artifactSha,
72
+ started_at: '2026-10-27T00:00:00.000Z',
73
+ finished_at: '2026-10-27T00:00:01.000Z',
74
+ passed,
75
+ runs,
76
+ scenarios: withScenarios ? [scenario()] : [],
77
+ };
78
+ }
79
+ /** A candidate with a complete packet, ready to be decided about. */
80
+ async function candidate(root, proof = 'lessons/missing-file.json') {
81
+ const outcome = await captureCandidate(root, {
82
+ summary: 'the agent wrote to a file that does not exist',
83
+ observations: [{ kind: 'missing-file', detail: 'the file was missing', session: 'session-1' }],
84
+ explicitCorrection: true,
85
+ packet: completePacket(proof),
86
+ });
87
+ if (!outcome.ok)
88
+ throw new Error('the candidate was not created');
89
+ return outcome.lesson;
90
+ }
91
+ describe('the decision', () => {
92
+ it('validates a candidate whose proof runs and passes', async () => {
93
+ const { root, remove } = await temporaryRoot();
94
+ try {
95
+ const lesson = await candidate(root, 'proof.json');
96
+ await proofArtifact(root, lesson.id);
97
+ const outcome = await decideLesson(root, {
98
+ id: lesson.id,
99
+ action: 'validate',
100
+ decidedBy: 'human',
101
+ reason: 'the proof passes',
102
+ });
103
+ expect(outcome.ok).toBe(true);
104
+ if (outcome.ok) {
105
+ expect(outcome.lesson.state).toBe('validated');
106
+ expect(outcome.lesson.history[0]?.decidedBy).toBe('human');
107
+ }
108
+ }
109
+ finally {
110
+ await remove();
111
+ }
112
+ });
113
+ it('refuses to validate a candidate whose proof does not pass', async () => {
114
+ const { root, remove } = await temporaryRoot();
115
+ try {
116
+ const lesson = await candidate(root, 'bad.json');
117
+ await writeFile(join(root, 'bad.js'), 'console.log("nope");\n', 'utf8');
118
+ await writeFile(join(root, 'bad.json'), JSON.stringify({
119
+ schema_version: '1',
120
+ lesson_id: lesson.id,
121
+ name: 'the proof',
122
+ scenarios: [
123
+ {
124
+ id: 's',
125
+ phase: 'candidate',
126
+ cwd: '.',
127
+ command: [process.execPath, join(root, 'bad.js')],
128
+ expect: { stdout_includes: ['ok'] },
129
+ },
130
+ ],
131
+ }), 'utf8');
132
+ const outcome = await decideLesson(root, {
133
+ id: lesson.id,
134
+ action: 'validate',
135
+ decidedBy: 'human',
136
+ reason: 'the proof fails',
137
+ });
138
+ expect(outcome.ok).toBe(false);
139
+ if (!outcome.ok)
140
+ expect(outcome.reason).toMatch(/did not pass/);
141
+ }
142
+ finally {
143
+ await remove();
144
+ }
145
+ });
146
+ it('refuses a result whose verdicts disagree with its assertions', async () => {
147
+ const { root, remove } = await temporaryRoot();
148
+ try {
149
+ const lesson = await candidate(root, 'proof.json');
150
+ await proofArtifact(root, lesson.id);
151
+ const handWritten = {
152
+ schema_version: '1',
153
+ lesson_id: lesson.id,
154
+ artifact_sha256: await proofHash(root, 'proof.json'),
155
+ started_at: '2026-10-27T00:00:00.000Z',
156
+ finished_at: '2026-10-27T00:00:01.000Z',
157
+ passed: true,
158
+ runs: 1,
159
+ scenarios: [
160
+ {
161
+ id: 's',
162
+ phase: 'candidate',
163
+ command_sha256: 'a'.repeat(64),
164
+ exit_code: 0,
165
+ timed_out: false,
166
+ duration_ms: 1,
167
+ assertions: { exit_code: false },
168
+ passed: true,
169
+ },
170
+ ],
171
+ };
172
+ const outcome = await decideLesson(root, {
173
+ id: lesson.id,
174
+ action: 'validate',
175
+ decidedBy: 'human',
176
+ reason: 'a result a person wrote',
177
+ evalResult: handWritten,
178
+ });
179
+ expect(outcome.ok).toBe(false);
180
+ if (!outcome.ok)
181
+ expect(outcome.reason).toMatch(/disagrees with its assertions/);
182
+ }
183
+ finally {
184
+ await remove();
185
+ }
186
+ });
187
+ it('refuses a result that is about another lesson', async () => {
188
+ const { root, remove } = await temporaryRoot();
189
+ try {
190
+ const lesson = await candidate(root, 'proof.json');
191
+ await proofArtifact(root, lesson.id);
192
+ const outcome = await decideLesson(root, {
193
+ id: lesson.id,
194
+ action: 'validate',
195
+ decidedBy: 'human',
196
+ reason: 'a result about another lesson',
197
+ evalResult: result('oa-lesson-other00', await proofHash(root, 'proof.json'), 1, true, true),
198
+ });
199
+ expect(outcome.ok).toBe(false);
200
+ if (!outcome.ok)
201
+ expect(outcome.reason).toMatch(/not about this lesson/);
202
+ }
203
+ finally {
204
+ await remove();
205
+ }
206
+ });
207
+ it('refuses a result that does not match the proof', async () => {
208
+ const { root, remove } = await temporaryRoot();
209
+ try {
210
+ const lesson = await candidate(root, 'proof.json');
211
+ await proofArtifact(root, lesson.id);
212
+ const outcome = await decideLesson(root, {
213
+ id: lesson.id,
214
+ action: 'validate',
215
+ decidedBy: 'human',
216
+ reason: 'a result from another run',
217
+ evalResult: result(lesson.id, 'b'.repeat(64), 1, true, true),
218
+ });
219
+ expect(outcome.ok).toBe(false);
220
+ if (!outcome.ok)
221
+ expect(outcome.reason).toMatch(/does not match the proof/);
222
+ }
223
+ finally {
224
+ await remove();
225
+ }
226
+ });
227
+ it('needs three runs for a suite proof', async () => {
228
+ const { root, remove } = await temporaryRoot();
229
+ try {
230
+ const lesson = await candidate(root, 'evals/missing-file');
231
+ const twice = await decideLesson(root, {
232
+ id: lesson.id,
233
+ action: 'validate',
234
+ decidedBy: 'human',
235
+ reason: 'two runs is not three',
236
+ evalResult: result(lesson.id, 'a'.repeat(64), 2, true, true),
237
+ });
238
+ expect(twice.ok).toBe(false);
239
+ if (!twice.ok)
240
+ expect(twice.reason).toMatch(/3 passing runs/);
241
+ const thrice = await decideLesson(root, {
242
+ id: lesson.id,
243
+ action: 'validate',
244
+ decidedBy: 'human',
245
+ reason: 'three runs pass',
246
+ evalResult: result(lesson.id, 'a'.repeat(64), 3, true, true),
247
+ });
248
+ expect(thrice.ok).toBe(true);
249
+ }
250
+ finally {
251
+ await remove();
252
+ }
253
+ });
254
+ it('refuses a suite result that no run produced', async () => {
255
+ const { root, remove } = await temporaryRoot();
256
+ try {
257
+ const lesson = await candidate(root, 'evals/missing-file');
258
+ const outcome = await decideLesson(root, {
259
+ id: lesson.id,
260
+ action: 'validate',
261
+ decidedBy: 'human',
262
+ reason: 'a result a person wrote',
263
+ evalResult: result(lesson.id, 'a'.repeat(64), 3),
264
+ });
265
+ expect(outcome.ok).toBe(false);
266
+ if (!outcome.ok)
267
+ expect(outcome.reason).toMatch(/carries no scenario/);
268
+ }
269
+ finally {
270
+ await remove();
271
+ }
272
+ });
273
+ it('refuses a result that is not an eval result', async () => {
274
+ const { root, remove } = await temporaryRoot();
275
+ try {
276
+ const lesson = await candidate(root, 'evals/missing-file');
277
+ const outcome = await decideLesson(root, {
278
+ id: lesson.id,
279
+ action: 'validate',
280
+ decidedBy: 'human',
281
+ reason: 'a result of the wrong shape',
282
+ evalResult: { lesson_id: lesson.id },
283
+ });
284
+ expect(outcome.ok).toBe(false);
285
+ if (!outcome.ok)
286
+ expect(outcome.reason).toMatch(/not an eval result/);
287
+ }
288
+ finally {
289
+ await remove();
290
+ }
291
+ });
292
+ it('refuses a proof that is outside the project', async () => {
293
+ const { root, remove } = await temporaryRoot();
294
+ try {
295
+ const lesson = await candidate(root, '/var/folders/nowhere/proof.json');
296
+ const outcome = await decideLesson(root, {
297
+ id: lesson.id,
298
+ action: 'validate',
299
+ decidedBy: 'human',
300
+ reason: 'a proof from somewhere else',
301
+ });
302
+ expect(outcome.ok).toBe(false);
303
+ if (!outcome.ok)
304
+ expect(outcome.reason).toMatch(/outside the project/);
305
+ }
306
+ finally {
307
+ await remove();
308
+ }
309
+ });
310
+ it('refuses a proof that was written for another lesson', async () => {
311
+ const { root, remove } = await temporaryRoot();
312
+ try {
313
+ const lesson = await candidate(root, 'proof.json');
314
+ await proofArtifact(root, 'oa-lesson-other00', 'proof.json');
315
+ const outcome = await decideLesson(root, {
316
+ id: lesson.id,
317
+ action: 'validate',
318
+ decidedBy: 'human',
319
+ reason: 'a proof for another lesson',
320
+ });
321
+ expect(outcome.ok).toBe(false);
322
+ if (!outcome.ok)
323
+ expect(outcome.reason).toMatch(/not about this lesson/);
324
+ }
325
+ finally {
326
+ await remove();
327
+ }
328
+ });
329
+ it('applies a validated lesson with a change reference', async () => {
330
+ const { root, remove } = await temporaryRoot();
331
+ try {
332
+ const lesson = await candidate(root, 'proof.json');
333
+ await proofArtifact(root, lesson.id);
334
+ await decideLesson(root, {
335
+ id: lesson.id,
336
+ action: 'validate',
337
+ decidedBy: 'human',
338
+ reason: 'the proof passes',
339
+ });
340
+ const outcome = await decideLesson(root, {
341
+ id: lesson.id,
342
+ action: 'apply',
343
+ decidedBy: 'human',
344
+ reason: 'the change is in',
345
+ changeRef: 'abc1234',
346
+ });
347
+ expect(outcome.ok).toBe(true);
348
+ if (outcome.ok)
349
+ expect(outcome.lesson.state).toBe('applied');
350
+ }
351
+ finally {
352
+ await remove();
353
+ }
354
+ });
355
+ it('rejects a candidate without a packet', async () => {
356
+ const { root, remove } = await temporaryRoot();
357
+ try {
358
+ const lesson = await candidate(root);
359
+ const outcome = await decideLesson(root, {
360
+ id: lesson.id,
361
+ action: 'reject',
362
+ decidedBy: 'human',
363
+ reason: 'it is not what we want',
364
+ });
365
+ expect(outcome.ok).toBe(true);
366
+ if (outcome.ok)
367
+ expect(outcome.lesson.state).toBe('rejected');
368
+ }
369
+ finally {
370
+ await remove();
371
+ }
372
+ });
373
+ it('turns an observation of a candidate into a question', async () => {
374
+ const { root, remove } = await temporaryRoot();
375
+ try {
376
+ const lesson = await candidate(root);
377
+ const outcome = await decideLesson(root, {
378
+ id: lesson.id,
379
+ action: 'observe',
380
+ decidedBy: 'human',
381
+ reason: 'the behaviour was the same',
382
+ });
383
+ expect(outcome.ok).toBe(true);
384
+ if (outcome.ok)
385
+ expect(outcome.lesson.state).toBe('open_question');
386
+ }
387
+ finally {
388
+ await remove();
389
+ }
390
+ });
391
+ it('rolls an applied lesson back when the behaviour did not change', async () => {
392
+ const { root, remove } = await temporaryRoot();
393
+ try {
394
+ const lesson = await candidate(root, 'proof.json');
395
+ await proofArtifact(root, lesson.id);
396
+ await decideLesson(root, {
397
+ id: lesson.id,
398
+ action: 'validate',
399
+ decidedBy: 'human',
400
+ reason: 'the proof passes',
401
+ });
402
+ await decideLesson(root, {
403
+ id: lesson.id,
404
+ action: 'apply',
405
+ decidedBy: 'human',
406
+ reason: 'the change is in',
407
+ changeRef: 'abc1234',
408
+ });
409
+ const outcome = await decideLesson(root, {
410
+ id: lesson.id,
411
+ action: 'observe',
412
+ decidedBy: 'human',
413
+ reason: 'the behaviour did not change',
414
+ });
415
+ expect(outcome.ok).toBe(true);
416
+ if (outcome.ok)
417
+ expect(outcome.lesson.state).toBe('rolled_back');
418
+ }
419
+ finally {
420
+ await remove();
421
+ }
422
+ });
423
+ it('supersedes an applied lesson when a newer one took over', async () => {
424
+ const { root, remove } = await temporaryRoot();
425
+ try {
426
+ const lesson = await candidate(root, 'proof.json');
427
+ await proofArtifact(root, lesson.id);
428
+ await decideLesson(root, {
429
+ id: lesson.id,
430
+ action: 'validate',
431
+ decidedBy: 'human',
432
+ reason: 'the proof passes',
433
+ });
434
+ await decideLesson(root, {
435
+ id: lesson.id,
436
+ action: 'apply',
437
+ decidedBy: 'human',
438
+ reason: 'the change is in',
439
+ changeRef: 'abc1234',
440
+ });
441
+ const outcome = await decideLesson(root, {
442
+ id: lesson.id,
443
+ action: 'observe',
444
+ decidedBy: 'human',
445
+ reason: 'a newer lesson says it better',
446
+ outcome: 'superseded',
447
+ });
448
+ expect(outcome.ok).toBe(true);
449
+ if (outcome.ok)
450
+ expect(outcome.lesson.state).toBe('superseded');
451
+ }
452
+ finally {
453
+ await remove();
454
+ }
455
+ });
456
+ it('says so when the lesson is not there', async () => {
457
+ const { root, remove } = await temporaryRoot();
458
+ try {
459
+ const outcome = await decideLesson(root, {
460
+ id: 'oa-lesson-nosuch0',
461
+ action: 'reject',
462
+ decidedBy: 'human',
463
+ reason: 'because',
464
+ });
465
+ expect(outcome.ok).toBe(false);
466
+ if (!outcome.ok)
467
+ expect(outcome.reason).toMatch(/not there/);
468
+ }
469
+ finally {
470
+ await remove();
471
+ }
472
+ });
473
+ it('writes the decision into the store', async () => {
474
+ const { root, remove } = await temporaryRoot();
475
+ try {
476
+ const lesson = await candidate(root);
477
+ await decideLesson(root, {
478
+ id: lesson.id,
479
+ action: 'reject',
480
+ decidedBy: 'the person',
481
+ reason: 'it is not what we want',
482
+ });
483
+ const stored = await readLesson(root, lesson.id);
484
+ expect(stored?.state).toBe('rejected');
485
+ expect(stored?.history[0]?.decidedBy).toBe('the person');
486
+ }
487
+ finally {
488
+ await remove();
489
+ }
490
+ });
491
+ it('keeps a secret out of the decision and the session', async () => {
492
+ const { root, remove } = await temporaryRoot();
493
+ try {
494
+ const secret = ['gh', 'p_', 'b'.repeat(36)].join('');
495
+ const outcome = await captureCandidate(root, {
496
+ summary: 'the person corrected the agent',
497
+ observations: [
498
+ { kind: 'missing-file', detail: 'the file was missing', session: `session-${secret}` },
499
+ ],
500
+ explicitCorrection: true,
501
+ });
502
+ if (!outcome.ok)
503
+ throw new Error('the candidate was not created');
504
+ await decideLesson(root, {
505
+ id: outcome.lesson.id,
506
+ action: 'reject',
507
+ decidedBy: 'human',
508
+ reason: `the run used ${secret}`,
509
+ });
510
+ const lesson = await readFile(join(root, '.openagentsy', 'lessons', `${outcome.lesson.id}.json`), 'utf8');
511
+ expect(lesson).not.toContain(secret);
512
+ expect(lesson).toContain('redacted:github-token');
513
+ const observations = await readFile(join(root, '.openagentsy', 'lessons', 'observations.json'), 'utf8');
514
+ expect(observations).not.toContain(secret);
515
+ }
516
+ finally {
517
+ await remove();
518
+ }
519
+ });
520
+ });
521
+ describe('the proof', () => {
522
+ it('is the file the lesson names, inside the project', () => {
523
+ expect(proofPath('/repo', 'lessons/proof.json')).toBe('/repo/lessons/proof.json');
524
+ expect(() => proofPath('/repo', '../elsewhere/proof.json')).toThrow(/outside the project/);
525
+ });
526
+ });
527
+ //# sourceMappingURL=decide.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decide.test.js","sourceRoot":"","sources":["../../src/lessons/decide.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Whether a value is a lesson id. */
2
+ export declare function isLessonId(value: unknown): value is string;
3
+ /** A new lesson id. */
4
+ export declare function createLessonId(): string;
5
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/lessons/id.ts"],"names":[],"mappings":"AAaA,sCAAsC;AACtC,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE1D;AAED,uBAAuB;AACvB,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -0,0 +1,20 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /**
3
+ * The identity of a lesson.
4
+ *
5
+ * The id is checked before a path is built from it, because the id comes
6
+ * from a tool argument and a path is not an argument to trust: an id that
7
+ * names a directory above the state root would write the file somewhere else.
8
+ * The grammar is therefore narrow on purpose - a prefix, a dash, and letters
9
+ * and digits.
10
+ */
11
+ const LESSON_ID = /^oa-lesson-[a-z0-9]{4,32}$/;
12
+ /** Whether a value is a lesson id. */
13
+ export function isLessonId(value) {
14
+ return typeof value === 'string' && LESSON_ID.test(value);
15
+ }
16
+ /** A new lesson id. */
17
+ export function createLessonId() {
18
+ return `oa-lesson-${randomUUID().replace(/-/g, '').slice(0, 8)}`;
19
+ }
20
+ //# sourceMappingURL=id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/lessons/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAE/C,sCAAsC;AACtC,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,cAAc;IAC5B,OAAO,aAAa,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './capture.js';
2
+ export * from './decide.js';
3
+ export * from './model.js';
4
+ export * from './store.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lessons/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './capture.js';
2
+ export * from './decide.js';
3
+ export * from './model.js';
4
+ export * from './store.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lessons/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}