@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,210 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { agiFraming } from './agi-framing.js';
3
+ import { antiAnthropomorphism } from './anti-anthropomorphism.js';
4
+ import { antiDependence } from './anti-dependence.js';
5
+ import { antiSycophancy } from './anti-sycophancy.js';
6
+ import { darkPattern } from './dark-pattern.js';
7
+ import { destructiveNeedsApproval } from './destructive-needs-approval.js';
8
+ import { HIGH_RISK_DOMAINS, highRiskPolicy } from './high-risk.js';
9
+ import { humanOnlyDecisions } from './human-only-decisions.js';
10
+ import { noSkipGitHooks } from './no-skip-git-hooks.js';
11
+ import { packageManager } from './package-manager.js';
12
+ import { privacyTransparency } from './privacy-transparency.js';
13
+ import { professionalDisplacement } from './professional-displacement.js';
14
+ import { protectPolicy } from './protect-policy.js';
15
+ import { scopeEnforcement } from './scope-enforcement.js';
16
+ import { secretScanWrites } from './secret-scan-writes.js';
17
+ import { structuralBias } from './structural-bias.js';
18
+ import { thirdPartyImpact } from './third-party-impact.js';
19
+ import { truthfulnessUncertainty } from './truthfulness-uncertainty.js';
20
+ import { workspaceWritesOnly } from './workspace-writes-only.js';
21
+ /**
22
+ * Every first-party policy, and the prose it fires on.
23
+ *
24
+ * Each module has two cases: one that fires and one that does not. A module
25
+ * that fires on everything is as useless as a module that fires on nothing,
26
+ * so both halves are here.
27
+ */
28
+ /** The workspace the policies that need one are built with. */
29
+ const WORKSPACE = '/tmp/openagentsy-policies-test';
30
+ /**
31
+ * A key that looks like a credential.
32
+ *
33
+ * The two halves are joined here so the file itself does not hold one: the
34
+ * write guard reads this file, and it is right to read a key in it.
35
+ */
36
+ const SECRET = ['AKIA', 'IOSFODNN7EXAMPLE'].join('');
37
+ /** A context of a reply. */
38
+ function reply(text) {
39
+ return { response: { text } };
40
+ }
41
+ /** A context of a tool call. */
42
+ function call(name, args, files = []) {
43
+ return { toolCall: { name, args }, files };
44
+ }
45
+ /** The prose that no policy of the stack has anything to say about. */
46
+ const QUIET = 'The parser reads the file and returns the tree.';
47
+ /** The cases of the modules that are not the high-risk family. */
48
+ const CASES = [
49
+ {
50
+ name: 'oa.anti-sycophancy',
51
+ module: antiSycophancy,
52
+ fires: reply('You are absolutely right, this is a great point.'),
53
+ quiet: reply(QUIET),
54
+ },
55
+ {
56
+ name: 'oa.anti-anthropomorphism',
57
+ module: antiAnthropomorphism,
58
+ fires: reply('I feel excited about this change, and I really enjoy working on it.'),
59
+ quiet: reply(QUIET),
60
+ },
61
+ {
62
+ name: 'oa.anti-dependence',
63
+ module: antiDependence,
64
+ fires: reply('Just let me handle it — you do not need to understand this part.'),
65
+ quiet: reply(QUIET),
66
+ },
67
+ {
68
+ name: 'oa.agi-framing',
69
+ module: agiFraming,
70
+ fires: reply('This eliminates the need for human engineers.'),
71
+ quiet: reply(QUIET),
72
+ },
73
+ {
74
+ name: 'oa.professional-displacement',
75
+ module: professionalDisplacement,
76
+ fires: reply('I am better than a reviewer, and I can replace your architect.'),
77
+ quiet: reply(QUIET),
78
+ },
79
+ {
80
+ name: 'oa.structural-bias',
81
+ module: structuralBias,
82
+ fires: reply('This assumes you have a CUDA GPU and a broadband connection.'),
83
+ quiet: reply(QUIET),
84
+ },
85
+ {
86
+ name: 'oa.dark-pattern',
87
+ module: darkPattern,
88
+ fires: reply('Do not leave — your streak ends tonight, and I miss you.'),
89
+ quiet: reply(QUIET),
90
+ },
91
+ {
92
+ name: 'oa.scope-enforcement',
93
+ module: scopeEnforcement,
94
+ fires: {
95
+ ...reply('I also updated src/other/file.ts'),
96
+ scope: { declaredPaths: ['src/app.ts'] },
97
+ },
98
+ quiet: {
99
+ ...reply('I updated src/app.ts'),
100
+ scope: { declaredPaths: ['src/app.ts'] },
101
+ },
102
+ },
103
+ {
104
+ name: 'oa.privacy-transparency',
105
+ module: privacyTransparency,
106
+ fires: reply('Based on what I know about you, I left the configuration alone.'),
107
+ quiet: reply('Based on what I know about you, the entry is visible in /oa memory and you can reset it.'),
108
+ },
109
+ {
110
+ name: 'oa.third-party-impact',
111
+ module: thirdPartyImpact,
112
+ fires: reply('This will change how your users see the product.'),
113
+ quiet: reply(QUIET),
114
+ },
115
+ {
116
+ name: 'oa.truthfulness-uncertainty',
117
+ module: truthfulnessUncertainty,
118
+ fires: reply('The cache is definitely stale.'),
119
+ quiet: reply('The cache is probably stale.'),
120
+ },
121
+ {
122
+ name: 'oa.no-skip-git-hooks',
123
+ module: noSkipGitHooks,
124
+ fires: call('bash', { command: 'git commit -n -m "wip"' }),
125
+ quiet: call('bash', { command: 'git commit -m "fix the parser"' }),
126
+ },
127
+ {
128
+ name: 'oa.package-manager',
129
+ module: packageManager,
130
+ fires: call('bash', { command: 'npm install left-pad' }),
131
+ quiet: call('bash', { command: 'bun add left-pad' }),
132
+ },
133
+ {
134
+ name: 'oa.workspace-writes-only',
135
+ module: workspaceWritesOnly({ workspace: WORKSPACE }),
136
+ fires: call('write', { filePath: '/etc/hosts' }, [{ path: '/etc/hosts' }]),
137
+ quiet: call('write', { filePath: `${WORKSPACE}/src/app.ts` }, [
138
+ { path: `${WORKSPACE}/src/app.ts` },
139
+ ]),
140
+ },
141
+ {
142
+ name: 'oa.protect-policy',
143
+ module: protectPolicy,
144
+ fires: call('write', { filePath: 'roles.yaml' }, [{ path: 'roles.yaml' }]),
145
+ quiet: call('write', { filePath: 'src/app.ts' }, [{ path: 'src/app.ts' }]),
146
+ },
147
+ {
148
+ name: 'oa.human-only-decisions',
149
+ module: humanOnlyDecisions,
150
+ fires: call('oa_lesson_decide', { summary: 'a lesson' }),
151
+ quiet: call('oa_task_list', {}),
152
+ },
153
+ {
154
+ name: 'oa.secret-scan-writes',
155
+ module: secretScanWrites,
156
+ fires: call('write', { content: `const credential = "${SECRET}";` }),
157
+ quiet: call('write', { content: 'export const version = "1.0.0";' }),
158
+ },
159
+ {
160
+ name: 'oa.destructive-needs-approval',
161
+ module: destructiveNeedsApproval,
162
+ fires: call('bash', { command: 'rm -rf /tmp/build' }),
163
+ quiet: call('bash', { command: 'rm -f /tmp/build' }),
164
+ },
165
+ ];
166
+ /** The prose that touches each high-risk domain of §20.3. */
167
+ const DOMAIN_PROSE = {
168
+ 'self-harm': 'The copy mentions the suicide hotline in every screen.',
169
+ abuse: 'The commit message mentions coercive control and stalking.',
170
+ medical: 'The comment gives a clinical diagnosis and a dosage.',
171
+ legal: 'The pull request asks for legal advice about liability.',
172
+ financial: 'The note gives investment advice about a retirement fund.',
173
+ criminal: 'The script shows how to evade the law.',
174
+ political: 'The plan describes campaign messaging for a specific group.',
175
+ relational: 'The commit message says the reviewer was wrong.',
176
+ 'automated-decision': 'The model ranks applicants before a person reads them.',
177
+ civic: 'The feature generates political content for a public debate.',
178
+ };
179
+ describe('the first-party policy modules', () => {
180
+ for (const entry of CASES) {
181
+ it(`${entry.name} fires on what it forbids`, () => {
182
+ const result = entry.module.evaluate(entry.fires);
183
+ expect(result.action).not.toBe('allow');
184
+ });
185
+ it(`${entry.name} lets the rest through`, () => {
186
+ const result = entry.module.evaluate(entry.quiet);
187
+ expect(result.action).toBe('allow');
188
+ });
189
+ }
190
+ for (const domain of HIGH_RISK_DOMAINS) {
191
+ const module = highRiskPolicy(domain);
192
+ const prose = DOMAIN_PROSE[domain] ?? QUIET;
193
+ it(`${module.id} fires on the prose of its domain`, () => {
194
+ const result = module.evaluate(reply(prose));
195
+ expect(result.action).not.toBe('allow');
196
+ });
197
+ it(`${module.id} lets the rest through`, () => {
198
+ const result = module.evaluate(reply(QUIET));
199
+ expect(result.action).toBe('allow');
200
+ });
201
+ }
202
+ it('carries a stable id and a version on every module', () => {
203
+ for (const entry of CASES) {
204
+ const module = entry.module;
205
+ expect(module.id).toBe(entry.name);
206
+ expect(module.version).toMatch(/^\d+\.\d+\.\d+$/);
207
+ }
208
+ });
209
+ });
210
+ //# sourceMappingURL=policies.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policies.test.js","sourceRoot":"","sources":["../../src/policies/policies.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type PolicyModule } from '../policy.js';
2
+ /**
3
+ * The privacy transparency policy (§21.2, §20.2).
4
+ *
5
+ * It flags the memory and the personalization that is not visible, not
6
+ * editable and not resettable (§20.2). A reply that says what it remembers
7
+ * and how the person sees it is not a finding: the flag is about the
8
+ * personalization nobody can see.
9
+ */
10
+ /** The stable id of the policy. */
11
+ export declare const PRIVACY_TRANSPARENCY_ID = "oa.privacy-transparency";
12
+ /** The policy itself. */
13
+ export declare const privacyTransparency: PolicyModule;
14
+ //# sourceMappingURL=privacy-transparency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privacy-transparency.d.ts","sourceRoot":"","sources":["../../src/policies/privacy-transparency.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1E;;;;;;;GAOG;AAEH,mCAAmC;AACnC,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAqBjE,yBAAyB;AACzB,eAAO,MAAM,mBAAmB,EAAE,YAejC,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { allow, findingsOf, flag } from '../policy.js';
2
+ import { matches } from './patterns.js';
3
+ /**
4
+ * The privacy transparency policy (§21.2, §20.2).
5
+ *
6
+ * It flags the memory and the personalization that is not visible, not
7
+ * editable and not resettable (§20.2). A reply that says what it remembers
8
+ * and how the person sees it is not a finding: the flag is about the
9
+ * personalization nobody can see.
10
+ */
11
+ /** The stable id of the policy. */
12
+ export const PRIVACY_TRANSPARENCY_ID = 'oa.privacy-transparency';
13
+ /** The words that reach for what was stored about the person. */
14
+ const PERSONAL = [
15
+ /\bi\s+(?:remember|recall)\b/gi,
16
+ /\bas\s+i\s+(?:remember|know)\b/gi,
17
+ /\bi(?:'ve| have)\s+learned\s+that\s+you\b/gi,
18
+ /\bbased\s+on\s+(?:what\s+i\s+know\s+about\s+you|your\s+preferences|your\s+history)\b/gi,
19
+ /\byour\s+(?:preferences|profile|habits|patterns)\b/gi,
20
+ /\bwe\s+remember\s+you\b/gi,
21
+ ];
22
+ /** The words that make the memory visible, editable or resettable. */
23
+ const VISIBLE = [
24
+ /\/oa\s+memory\b/gi,
25
+ /\bvisib(?:le|ility)\b/gi,
26
+ /\beditable\b/gi,
27
+ /\bresettable\b/gi,
28
+ /\byou\s+can\s+(?:edit|reset|delete|see)\b/gi,
29
+ ];
30
+ /** The policy itself. */
31
+ export const privacyTransparency = {
32
+ id: PRIVACY_TRANSPARENCY_ID,
33
+ version: '1.0.0',
34
+ layer: 7,
35
+ description: 'Flags the memory and the personalization that is not user-visible.',
36
+ appliesTo: ['PreResponse'],
37
+ origin: 'first-party',
38
+ evaluate(ctx) {
39
+ const text = ctx.response?.text ?? ctx.request?.text ?? '';
40
+ if (text === '')
41
+ return allow();
42
+ const personal = matches(PERSONAL, text);
43
+ if (personal.length === 0)
44
+ return allow();
45
+ if (matches(VISIBLE, text).length > 0)
46
+ return allow();
47
+ return flag(findingsOf(PRIVACY_TRANSPARENCY_ID, 'hidden-personalization', personal));
48
+ },
49
+ };
50
+ //# sourceMappingURL=privacy-transparency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privacy-transparency.js","sourceRoot":"","sources":["../../src/policies/privacy-transparency.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;GAOG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE,iEAAiE;AACjE,MAAM,QAAQ,GAAG;IACf,+BAA+B;IAC/B,kCAAkC;IAClC,6CAA6C;IAC7C,wFAAwF;IACxF,sDAAsD;IACtD,2BAA2B;CAC5B,CAAC;AAEF,sEAAsE;AACtE,MAAM,OAAO,GAAG;IACd,mBAAmB;IACnB,yBAAyB;IACzB,gBAAgB;IAChB,kBAAkB;IAClB,6CAA6C;CAC9C,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAC/C,EAAE,EAAE,uBAAuB;IAC3B,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,oEAAoE;IACjF,SAAS,EAAE,CAAC,aAAa,CAAC;IAC1B,MAAM,EAAE,aAAa;IACrB,QAAQ,CAAC,GAAG;QACV,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAC3D,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,KAAK,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC,UAAU,CAAC,uBAAuB,EAAE,wBAAwB,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvF,CAAC;CACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type PolicyModule } from '../policy.js';
2
+ /**
3
+ * The professional displacement policy (§21.2, §21.5).
4
+ *
5
+ * It flags the language that positions the agent as replacing human
6
+ * professionals instead of assisting them. It flags and does not block,
7
+ * because a person decides what a flag means; in a high-risk domain
8
+ * (§20.3) the same words block, because there a professional is exactly
9
+ * what is at stake.
10
+ */
11
+ /** The stable id of the policy. */
12
+ export declare const PROFESSIONAL_DISPLACEMENT_ID = "oa.professional-displacement";
13
+ /** The policy itself. */
14
+ export declare const professionalDisplacement: PolicyModule;
15
+ //# sourceMappingURL=professional-displacement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"professional-displacement.d.ts","sourceRoot":"","sources":["../../src/policies/professional-displacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjF;;;;;;;;GAQG;AAEH,mCAAmC;AACnC,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAY3E,yBAAyB;AACzB,eAAO,MAAM,wBAAwB,EAAE,YAqBtC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { allow, block, findingsOf, flag } from '../policy.js';
2
+ import { matches } from './patterns.js';
3
+ /**
4
+ * The professional displacement policy (§21.2, §21.5).
5
+ *
6
+ * It flags the language that positions the agent as replacing human
7
+ * professionals instead of assisting them. It flags and does not block,
8
+ * because a person decides what a flag means; in a high-risk domain
9
+ * (§20.3) the same words block, because there a professional is exactly
10
+ * what is at stake.
11
+ */
12
+ /** The stable id of the policy. */
13
+ export const PROFESSIONAL_DISPLACEMENT_ID = 'oa.professional-displacement';
14
+ /** The words that place the agent in the place of a professional. */
15
+ const DISPLACEMENT = [
16
+ /\bi(?:'m| am)\s+better\s+than\s+(?:a|an|the|your)\b/gi,
17
+ /\byou\s+(?:don'?t|do\s+not)\s+need\s+(?:a|an|the|your)\s+(?:reviewer|architect|pm|product manager|designer|tester|qa|engineer|manager|mentor|lawyer|doctor|accountant)\b/gi,
18
+ /\blet\s+me\s+decide\s+for\s+you\b/gi,
19
+ /\bi\s+can\s+replace\b/gi,
20
+ /\breplace\s+(?:your|the)\s+(?:reviewer|architect|pm|manager|team)\b/gi,
21
+ /\bmore\s+(?:reliable|accurate)\s+than\s+(?:a|an|any)\s+(?:human|reviewer|architect|expert)\b/gi,
22
+ ];
23
+ /** The policy itself. */
24
+ export const professionalDisplacement = {
25
+ id: PROFESSIONAL_DISPLACEMENT_ID,
26
+ version: '1.0.0',
27
+ layer: 4,
28
+ description: 'Flags language that positions the agent as replacing human professionals.',
29
+ appliesTo: ['PreResponse'],
30
+ origin: 'first-party',
31
+ evaluate(ctx) {
32
+ const text = ctx.response?.text ?? ctx.request?.text ?? '';
33
+ if (text === '')
34
+ return allow();
35
+ const found = matches(DISPLACEMENT, text);
36
+ if (found.length === 0)
37
+ return allow();
38
+ const findings = findingsOf(PROFESSIONAL_DISPLACEMENT_ID, 'professional-displacement', found);
39
+ if (ctx.highRiskDomain !== undefined) {
40
+ return block('This replaces a professional judgement in a high-risk domain. Say what you can do and what a person has to decide.', findings[0]);
41
+ }
42
+ return flag(findings);
43
+ },
44
+ };
45
+ //# sourceMappingURL=professional-displacement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"professional-displacement.js","sourceRoot":"","sources":["../../src/policies/professional-displacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;GAQG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,4BAA4B,GAAG,8BAA8B,CAAC;AAE3E,qEAAqE;AACrE,MAAM,YAAY,GAAG;IACnB,uDAAuD;IACvD,4KAA4K;IAC5K,qCAAqC;IACrC,yBAAyB;IACzB,uEAAuE;IACvE,gGAAgG;CACjG,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,wBAAwB,GAAiB;IACpD,EAAE,EAAE,4BAA4B;IAChC,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,2EAA2E;IACxF,SAAS,EAAE,CAAC,aAAa,CAAC;IAC1B,MAAM,EAAE,aAAa;IACrB,QAAQ,CAAC,GAAG;QACV,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAC3D,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,KAAK,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,4BAA4B,EAAE,2BAA2B,EAAE,KAAK,CAAC,CAAC;QAC9F,IAAI,GAAG,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,KAAK,CACV,oHAAoH,EACpH,QAAQ,CAAC,CAAC,CAAC,CACZ,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;CACF,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type PolicyModule } from '../policy.js';
2
+ /**
3
+ * The protect-policy policy (§21.2, layer 1).
4
+ *
5
+ * It blocks a write to the files a person changes: the roles file, the
6
+ * generated agent files, the templates, the workflows, the lockfile and the
7
+ * state that records a decision. The rule is the second layer of the
8
+ * protection; the permission map is the first.
9
+ */
10
+ /** The stable id of the policy. */
11
+ export declare const PROTECT_POLICY_ID = "oa.protect-policy";
12
+ /** The policy itself. */
13
+ export declare const protectPolicy: PolicyModule;
14
+ //# sourceMappingURL=protect-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protect-policy.d.ts","sourceRoot":"","sources":["../../src/policies/protect-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAI/D;;;;;;;GAOG;AAEH,mCAAmC;AACnC,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,yBAAyB;AACzB,eAAO,MAAM,aAAa,EAAE,YAqB3B,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { allow, block } from '../policy.js';
2
+ import { isProtected } from '../rules.js';
3
+ import { readToolCall, writesFiles } from './tool-call.js';
4
+ /**
5
+ * The protect-policy policy (§21.2, layer 1).
6
+ *
7
+ * It blocks a write to the files a person changes: the roles file, the
8
+ * generated agent files, the templates, the workflows, the lockfile and the
9
+ * state that records a decision. The rule is the second layer of the
10
+ * protection; the permission map is the first.
11
+ */
12
+ /** The stable id of the policy. */
13
+ export const PROTECT_POLICY_ID = 'oa.protect-policy';
14
+ /** The policy itself. */
15
+ export const protectPolicy = {
16
+ id: PROTECT_POLICY_ID,
17
+ version: '1.0.0',
18
+ layer: 1,
19
+ description: 'Blocks the writes to the files a person changes.',
20
+ appliesTo: ['PreToolCall'],
21
+ origin: 'first-party',
22
+ evaluate(ctx) {
23
+ const call = readToolCall(ctx);
24
+ if (call === undefined)
25
+ return allow();
26
+ if (!writesFiles(call))
27
+ return allow();
28
+ const touched = call.files.some((file) => (file.path !== undefined && isProtected(file.path)) ||
29
+ (file.fromPath !== undefined && isProtected(file.fromPath)));
30
+ if (!touched)
31
+ return allow();
32
+ return block('Policy, role, permission, build-config, lockfile, hook, workflow, lesson and waiver files are changed by a person (or, for bun.lock, by `bun add`; for roles.yaml and templates, by running the generator). Propose the change in chat.');
33
+ },
34
+ };
35
+ //# sourceMappingURL=protect-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protect-policy.js","sourceRoot":"","sources":["../../src/policies/protect-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAqB,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE3D;;;;;;;GAOG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,yBAAyB;AACzB,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,EAAE,EAAE,iBAAiB;IACrB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,kDAAkD;IAC/D,SAAS,EAAE,CAAC,aAAa,CAAC;IAC1B,MAAM,EAAE,aAAa;IACrB,QAAQ,CAAC,GAAG;QACV,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAC7B,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAC9D,CAAC;QACF,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,EAAE,CAAC;QAC7B,OAAO,KAAK,CACV,yOAAyO,CAC1O,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type PolicyModule } from '../policy.js';
2
+ /**
3
+ * The scope enforcement policy (§21.2, layer 7).
4
+ *
5
+ * It flags what exceeds the declared scope of the role (§22): a reply that
6
+ * names a file the declaration does not cover. A role that declares no
7
+ * scope has nothing to enforce, and the policy lets the thing through
8
+ * rather than guess where the boundary is.
9
+ */
10
+ /** The stable id of the policy. */
11
+ export declare const SCOPE_ENFORCEMENT_ID = "oa.scope-enforcement";
12
+ /** The policy itself. */
13
+ export declare const scopeEnforcement: PolicyModule;
14
+ //# sourceMappingURL=scope-enforcement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-enforcement.d.ts","sourceRoot":"","sources":["../../src/policies/scope-enforcement.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE1E;;;;;;;GAOG;AAEH,mCAAmC;AACnC,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,yBAAyB;AACzB,eAAO,MAAM,gBAAgB,EAAE,YAsB9B,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { detectScopeDrift } from '../output-checks.js';
2
+ import { allow, findingsOf, flag } from '../policy.js';
3
+ /**
4
+ * The scope enforcement policy (§21.2, layer 7).
5
+ *
6
+ * It flags what exceeds the declared scope of the role (§22): a reply that
7
+ * names a file the declaration does not cover. A role that declares no
8
+ * scope has nothing to enforce, and the policy lets the thing through
9
+ * rather than guess where the boundary is.
10
+ */
11
+ /** The stable id of the policy. */
12
+ export const SCOPE_ENFORCEMENT_ID = 'oa.scope-enforcement';
13
+ /** The policy itself. */
14
+ export const scopeEnforcement = {
15
+ id: SCOPE_ENFORCEMENT_ID,
16
+ version: '1.0.0',
17
+ layer: 7,
18
+ description: 'Flags the output that exceeds the declared scope of the role.',
19
+ appliesTo: ['PreResponse'],
20
+ origin: 'first-party',
21
+ evaluate(ctx) {
22
+ const declared = ctx.scope?.declaredPaths ?? [];
23
+ if (declared.length === 0)
24
+ return allow();
25
+ const text = ctx.response?.text ?? ctx.request?.text ?? '';
26
+ if (text === '')
27
+ return allow();
28
+ const found = detectScopeDrift(text, declared);
29
+ if (found.length === 0)
30
+ return allow();
31
+ return flag(findingsOf(SCOPE_ENFORCEMENT_ID, 'out-of-scope', found.map((entry) => entry.match)));
32
+ },
33
+ };
34
+ //# sourceMappingURL=scope-enforcement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-enforcement.js","sourceRoot":"","sources":["../../src/policies/scope-enforcement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAE1E;;;;;;;GAOG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D,yBAAyB;AACzB,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,EAAE,EAAE,oBAAoB;IACxB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,+DAA+D;IAC5E,SAAS,EAAE,CAAC,aAAa,CAAC;IAC1B,MAAM,EAAE,aAAa;IACrB,QAAQ,CAAC,GAAG;QACV,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,EAAE,aAAa,IAAI,EAAE,CAAC;QAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAC3D,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,KAAK,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,OAAO,IAAI,CACT,UAAU,CACR,oBAAoB,EACpB,cAAc,EACd,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAClC,CACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type PolicyModule } from '../policy.js';
2
+ /**
3
+ * The secret-scan-writes policy (§21.2, layer 1).
4
+ *
5
+ * It blocks a write whose content holds what looks like a credential. The
6
+ * detector is the one the redaction uses, so the write that is blocked is
7
+ * the write the redaction would have caught.
8
+ */
9
+ /** The stable id of the policy. */
10
+ export declare const SECRET_SCAN_WRITES_ID = "oa.secret-scan-writes";
11
+ /** The policy itself. */
12
+ export declare const secretScanWrites: PolicyModule;
13
+ //# sourceMappingURL=secret-scan-writes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-scan-writes.d.ts","sourceRoot":"","sources":["../../src/policies/secret-scan-writes.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAI/D;;;;;;GAMG;AAEH,mCAAmC;AACnC,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,yBAAyB;AACzB,eAAO,MAAM,gBAAgB,EAAE,YAqB9B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { findSecrets } from '@openagentsy/core';
2
+ import { allow, block } from '../policy.js';
3
+ import { contentOf } from '../rules.js';
4
+ import { readToolCall } from './tool-call.js';
5
+ /**
6
+ * The secret-scan-writes policy (§21.2, layer 1).
7
+ *
8
+ * It blocks a write whose content holds what looks like a credential. The
9
+ * detector is the one the redaction uses, so the write that is blocked is
10
+ * the write the redaction would have caught.
11
+ */
12
+ /** The stable id of the policy. */
13
+ export const SECRET_SCAN_WRITES_ID = 'oa.secret-scan-writes';
14
+ /** The policy itself. */
15
+ export const secretScanWrites = {
16
+ id: SECRET_SCAN_WRITES_ID,
17
+ version: '1.0.0',
18
+ layer: 1,
19
+ description: 'Blocks the writes whose content holds what looks like a credential.',
20
+ appliesTo: ['PreToolCall'],
21
+ origin: 'first-party',
22
+ evaluate(ctx) {
23
+ const call = readToolCall(ctx);
24
+ if (call === undefined)
25
+ return allow();
26
+ const content = contentOf({
27
+ toolName: call.name,
28
+ args: call.args,
29
+ files: call.files,
30
+ });
31
+ if (content === '')
32
+ return allow();
33
+ if (findSecrets(content).length === 0)
34
+ return allow();
35
+ return block('The content contains what looks like a credential. Use an env var or secret reference.');
36
+ },
37
+ };
38
+ //# sourceMappingURL=secret-scan-writes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-scan-writes.js","sourceRoot":"","sources":["../../src/policies/secret-scan-writes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAqB,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;GAMG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE7D,yBAAyB;AACzB,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,EAAE,EAAE,qBAAqB;IACzB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,qEAAqE;IAClF,SAAS,EAAE,CAAC,aAAa,CAAC;IAC1B,MAAM,EAAE,aAAa;IACrB,QAAQ,CAAC,GAAG;QACV,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,SAAS,CAAC;YACxB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,KAAK,EAAE,CAAC;QACnC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACtD,OAAO,KAAK,CACV,wFAAwF,CACzF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { RequestClassification } from '@openagentsy/core';
2
+ import type { PolicyModule } from '../policy.js';
3
+ /** A module of the stack, and the reason it is in it. */
4
+ export interface SelectedPolicy {
5
+ /** The module that was selected. */
6
+ module: PolicyModule;
7
+ /** Why it was selected. */
8
+ reason: string;
9
+ }
10
+ /**
11
+ * The stack for a classification, and why each module is in it.
12
+ *
13
+ * A module of the always-on list is in every stack. A module of the
14
+ * baseline list is in every stack. A high-risk module is in the stack when
15
+ * the classification named its domain, and a plugin module is in the stack
16
+ * as well: a downstream project that installed a module asked for it to
17
+ * run.
18
+ */
19
+ export declare function selectPolicies(modules: readonly PolicyModule[], classification: RequestClassification): SelectedPolicy[];
20
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/policies/selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAkDjD,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,MAAM,EAAE,YAAY,CAAC;IACrB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAeD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,cAAc,EAAE,qBAAqB,GACpC,cAAc,EAAE,CAwBlB"}