@openagentsy/hooks 0.0.0-stage → 0.2.1
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.
- package/LICENSE +674 -0
- package/README.md +32 -2
- package/dist/accountability.d.ts +29 -0
- package/dist/accountability.d.ts.map +1 -0
- package/dist/accountability.js +21 -0
- package/dist/accountability.js.map +1 -0
- package/dist/accountability.test.d.ts +2 -0
- package/dist/accountability.test.d.ts.map +1 -0
- package/dist/accountability.test.js +42 -0
- package/dist/accountability.test.js.map +1 -0
- package/dist/approvals.d.ts +110 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +464 -0
- package/dist/approvals.js.map +1 -0
- package/dist/approvals.test.d.ts +2 -0
- package/dist/approvals.test.d.ts.map +1 -0
- package/dist/approvals.test.js +307 -0
- package/dist/approvals.test.js.map +1 -0
- package/dist/base-tool.d.ts +26 -0
- package/dist/base-tool.d.ts.map +1 -0
- package/dist/base-tool.js +37 -0
- package/dist/base-tool.js.map +1 -0
- package/dist/base-tool.test.d.ts +2 -0
- package/dist/base-tool.test.d.ts.map +1 -0
- package/dist/base-tool.test.js +34 -0
- package/dist/base-tool.test.js.map +1 -0
- package/dist/eval/index.d.ts +3 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +3 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/runner.d.ts +179 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +616 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/eval/runner.test.d.ts +2 -0
- package/dist/eval/runner.test.d.ts.map +1 -0
- package/dist/eval/runner.test.js +431 -0
- package/dist/eval/runner.test.js.map +1 -0
- package/dist/eval/types.d.ts +173 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +104 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/event.d.ts +59 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +178 -0
- package/dist/event.js.map +1 -0
- package/dist/event.test.d.ts +2 -0
- package/dist/event.test.d.ts.map +1 -0
- package/dist/event.test.js +49 -0
- package/dist/event.test.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/lessons/capture.d.ts +66 -0
- package/dist/lessons/capture.d.ts.map +1 -0
- package/dist/lessons/capture.js +166 -0
- package/dist/lessons/capture.js.map +1 -0
- package/dist/lessons/capture.test.d.ts +2 -0
- package/dist/lessons/capture.test.d.ts.map +1 -0
- package/dist/lessons/capture.test.js +200 -0
- package/dist/lessons/capture.test.js.map +1 -0
- package/dist/lessons/decide.d.ts +90 -0
- package/dist/lessons/decide.d.ts.map +1 -0
- package/dist/lessons/decide.js +334 -0
- package/dist/lessons/decide.js.map +1 -0
- package/dist/lessons/decide.test.d.ts +2 -0
- package/dist/lessons/decide.test.d.ts.map +1 -0
- package/dist/lessons/decide.test.js +527 -0
- package/dist/lessons/decide.test.js.map +1 -0
- package/dist/lessons/id.d.ts +5 -0
- package/dist/lessons/id.d.ts.map +1 -0
- package/dist/lessons/id.js +20 -0
- package/dist/lessons/id.js.map +1 -0
- package/dist/lessons/index.d.ts +5 -0
- package/dist/lessons/index.d.ts.map +1 -0
- package/dist/lessons/index.js +5 -0
- package/dist/lessons/index.js.map +1 -0
- package/dist/lessons/model.d.ts +163 -0
- package/dist/lessons/model.d.ts.map +1 -0
- package/dist/lessons/model.js +181 -0
- package/dist/lessons/model.js.map +1 -0
- package/dist/lessons/model.test.d.ts +2 -0
- package/dist/lessons/model.test.d.ts.map +1 -0
- package/dist/lessons/model.test.js +178 -0
- package/dist/lessons/model.test.js.map +1 -0
- package/dist/lessons/permissions.test.d.ts +2 -0
- package/dist/lessons/permissions.test.d.ts.map +1 -0
- package/dist/lessons/permissions.test.js +88 -0
- package/dist/lessons/permissions.test.js.map +1 -0
- package/dist/lessons/store.d.ts +74 -0
- package/dist/lessons/store.d.ts.map +1 -0
- package/dist/lessons/store.js +231 -0
- package/dist/lessons/store.js.map +1 -0
- package/dist/output-checks.d.ts +64 -0
- package/dist/output-checks.d.ts.map +1 -0
- package/dist/output-checks.js +248 -0
- package/dist/output-checks.js.map +1 -0
- package/dist/output-checks.test.d.ts +2 -0
- package/dist/output-checks.test.d.ts.map +1 -0
- package/dist/output-checks.test.js +58 -0
- package/dist/output-checks.test.js.map +1 -0
- package/dist/paths.d.ts +37 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +70 -0
- package/dist/paths.js.map +1 -0
- package/dist/paths.test.d.ts +2 -0
- package/dist/paths.test.d.ts.map +1 -0
- package/dist/paths.test.js +36 -0
- package/dist/paths.test.js.map +1 -0
- package/dist/policies/agi-framing.d.ts +12 -0
- package/dist/policies/agi-framing.d.ts.map +1 -0
- package/dist/policies/agi-framing.js +33 -0
- package/dist/policies/agi-framing.js.map +1 -0
- package/dist/policies/anti-anthropomorphism.d.ts +13 -0
- package/dist/policies/anti-anthropomorphism.d.ts.map +1 -0
- package/dist/policies/anti-anthropomorphism.js +34 -0
- package/dist/policies/anti-anthropomorphism.js.map +1 -0
- package/dist/policies/anti-dependence.d.ts +12 -0
- package/dist/policies/anti-dependence.d.ts.map +1 -0
- package/dist/policies/anti-dependence.js +33 -0
- package/dist/policies/anti-dependence.js.map +1 -0
- package/dist/policies/anti-sycophancy.d.ts +13 -0
- package/dist/policies/anti-sycophancy.d.ts.map +1 -0
- package/dist/policies/anti-sycophancy.js +34 -0
- package/dist/policies/anti-sycophancy.js.map +1 -0
- package/dist/policies/dark-pattern.d.ts +14 -0
- package/dist/policies/dark-pattern.d.ts.map +1 -0
- package/dist/policies/dark-pattern.js +44 -0
- package/dist/policies/dark-pattern.js.map +1 -0
- package/dist/policies/destructive-needs-approval.d.ts +14 -0
- package/dist/policies/destructive-needs-approval.d.ts.map +1 -0
- package/dist/policies/destructive-needs-approval.js +31 -0
- package/dist/policies/destructive-needs-approval.js.map +1 -0
- package/dist/policies/discovery.d.ts +12 -0
- package/dist/policies/discovery.d.ts.map +1 -0
- package/dist/policies/discovery.js +130 -0
- package/dist/policies/discovery.js.map +1 -0
- package/dist/policies/high-risk.d.ts +25 -0
- package/dist/policies/high-risk.d.ts.map +1 -0
- package/dist/policies/high-risk.js +105 -0
- package/dist/policies/high-risk.js.map +1 -0
- package/dist/policies/human-only-decisions.d.ts +14 -0
- package/dist/policies/human-only-decisions.d.ts.map +1 -0
- package/dist/policies/human-only-decisions.js +33 -0
- package/dist/policies/human-only-decisions.js.map +1 -0
- package/dist/policies/index.d.ts +29 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +82 -0
- package/dist/policies/index.js.map +1 -0
- package/dist/policies/no-skip-git-hooks.d.ts +14 -0
- package/dist/policies/no-skip-git-hooks.d.ts.map +1 -0
- package/dist/policies/no-skip-git-hooks.js +31 -0
- package/dist/policies/no-skip-git-hooks.js.map +1 -0
- package/dist/policies/package-manager.d.ts +12 -0
- package/dist/policies/package-manager.d.ts.map +1 -0
- package/dist/policies/package-manager.js +29 -0
- package/dist/policies/package-manager.js.map +1 -0
- package/dist/policies/patterns.d.ts +17 -0
- package/dist/policies/patterns.d.ts.map +1 -0
- package/dist/policies/patterns.js +30 -0
- package/dist/policies/patterns.js.map +1 -0
- package/dist/policies/policies.test.d.ts +2 -0
- package/dist/policies/policies.test.d.ts.map +1 -0
- package/dist/policies/policies.test.js +210 -0
- package/dist/policies/policies.test.js.map +1 -0
- package/dist/policies/privacy-transparency.d.ts +14 -0
- package/dist/policies/privacy-transparency.d.ts.map +1 -0
- package/dist/policies/privacy-transparency.js +50 -0
- package/dist/policies/privacy-transparency.js.map +1 -0
- package/dist/policies/professional-displacement.d.ts +15 -0
- package/dist/policies/professional-displacement.d.ts.map +1 -0
- package/dist/policies/professional-displacement.js +45 -0
- package/dist/policies/professional-displacement.js.map +1 -0
- package/dist/policies/protect-policy.d.ts +14 -0
- package/dist/policies/protect-policy.d.ts.map +1 -0
- package/dist/policies/protect-policy.js +35 -0
- package/dist/policies/protect-policy.js.map +1 -0
- package/dist/policies/scope-enforcement.d.ts +14 -0
- package/dist/policies/scope-enforcement.d.ts.map +1 -0
- package/dist/policies/scope-enforcement.js +34 -0
- package/dist/policies/scope-enforcement.js.map +1 -0
- package/dist/policies/secret-scan-writes.d.ts +13 -0
- package/dist/policies/secret-scan-writes.d.ts.map +1 -0
- package/dist/policies/secret-scan-writes.js +38 -0
- package/dist/policies/secret-scan-writes.js.map +1 -0
- package/dist/policies/selection.d.ts +20 -0
- package/dist/policies/selection.d.ts.map +1 -0
- package/dist/policies/selection.js +93 -0
- package/dist/policies/selection.js.map +1 -0
- package/dist/policies/structural-bias.d.ts +14 -0
- package/dist/policies/structural-bias.d.ts.map +1 -0
- package/dist/policies/structural-bias.js +41 -0
- package/dist/policies/structural-bias.js.map +1 -0
- package/dist/policies/third-party-impact.d.ts +13 -0
- package/dist/policies/third-party-impact.d.ts.map +1 -0
- package/dist/policies/third-party-impact.js +38 -0
- package/dist/policies/third-party-impact.js.map +1 -0
- package/dist/policies/tool-call.d.ts +38 -0
- package/dist/policies/tool-call.d.ts.map +1 -0
- package/dist/policies/tool-call.js +53 -0
- package/dist/policies/tool-call.js.map +1 -0
- package/dist/policies/truthfulness-uncertainty.d.ts +13 -0
- package/dist/policies/truthfulness-uncertainty.d.ts.map +1 -0
- package/dist/policies/truthfulness-uncertainty.js +45 -0
- package/dist/policies/truthfulness-uncertainty.js.map +1 -0
- package/dist/policies/workspace-writes-only.d.ts +25 -0
- package/dist/policies/workspace-writes-only.d.ts.map +1 -0
- package/dist/policies/workspace-writes-only.js +54 -0
- package/dist/policies/workspace-writes-only.js.map +1 -0
- package/dist/policy-engine.d.ts +69 -0
- package/dist/policy-engine.d.ts.map +1 -0
- package/dist/policy-engine.js +145 -0
- package/dist/policy-engine.js.map +1 -0
- package/dist/policy-registry.d.ts +62 -0
- package/dist/policy-registry.d.ts.map +1 -0
- package/dist/policy-registry.js +63 -0
- package/dist/policy-registry.js.map +1 -0
- package/dist/policy-registry.test.d.ts +2 -0
- package/dist/policy-registry.test.d.ts.map +1 -0
- package/dist/policy-registry.test.js +79 -0
- package/dist/policy-registry.test.js.map +1 -0
- package/dist/policy-release.d.ts +44 -0
- package/dist/policy-release.d.ts.map +1 -0
- package/dist/policy-release.js +65 -0
- package/dist/policy-release.js.map +1 -0
- package/dist/policy.d.ts +141 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +22 -0
- package/dist/policy.js.map +1 -0
- package/dist/quality/audit.d.ts +56 -0
- package/dist/quality/audit.d.ts.map +1 -0
- package/dist/quality/audit.js +52 -0
- package/dist/quality/audit.js.map +1 -0
- package/dist/quality/findings.d.ts +34 -0
- package/dist/quality/findings.d.ts.map +1 -0
- package/dist/quality/findings.js +121 -0
- package/dist/quality/findings.js.map +1 -0
- package/dist/quality/findings.test.d.ts +2 -0
- package/dist/quality/findings.test.d.ts.map +1 -0
- package/dist/quality/findings.test.js +79 -0
- package/dist/quality/findings.test.js.map +1 -0
- package/dist/quality/index.d.ts +20 -0
- package/dist/quality/index.d.ts.map +1 -0
- package/dist/quality/index.js +20 -0
- package/dist/quality/index.js.map +1 -0
- package/dist/quality/rule.d.ts +43 -0
- package/dist/quality/rule.d.ts.map +1 -0
- package/dist/quality/rule.js +162 -0
- package/dist/quality/rule.js.map +1 -0
- package/dist/quality/rule.test.d.ts +2 -0
- package/dist/quality/rule.test.d.ts.map +1 -0
- package/dist/quality/rule.test.js +187 -0
- package/dist/quality/rule.test.js.map +1 -0
- package/dist/quality/tools.d.ts +30 -0
- package/dist/quality/tools.d.ts.map +1 -0
- package/dist/quality/tools.js +33 -0
- package/dist/quality/tools.js.map +1 -0
- package/dist/quality/tools.test.d.ts +2 -0
- package/dist/quality/tools.test.d.ts.map +1 -0
- package/dist/quality/tools.test.js +41 -0
- package/dist/quality/tools.test.js.map +1 -0
- package/dist/quality/waive.d.ts +37 -0
- package/dist/quality/waive.d.ts.map +1 -0
- package/dist/quality/waive.js +39 -0
- package/dist/quality/waive.js.map +1 -0
- package/dist/quality/waivers.d.ts +63 -0
- package/dist/quality/waivers.d.ts.map +1 -0
- package/dist/quality/waivers.js +132 -0
- package/dist/quality/waivers.js.map +1 -0
- package/dist/quality/waivers.test.d.ts +2 -0
- package/dist/quality/waivers.test.d.ts.map +1 -0
- package/dist/quality/waivers.test.js +138 -0
- package/dist/quality/waivers.test.js.map +1 -0
- package/dist/registry.d.ts +86 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +92 -0
- package/dist/registry.js.map +1 -0
- package/dist/registry.test.d.ts +2 -0
- package/dist/registry.test.d.ts.map +1 -0
- package/dist/registry.test.js +117 -0
- package/dist/registry.test.js.map +1 -0
- package/dist/rules.d.ts +107 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +632 -0
- package/dist/rules.js.map +1 -0
- package/dist/rules.test.d.ts +2 -0
- package/dist/rules.test.d.ts.map +1 -0
- package/dist/rules.test.js +488 -0
- package/dist/rules.test.js.map +1 -0
- package/dist/secrets.d.ts +17 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +17 -0
- package/dist/secrets.js.map +1 -0
- package/dist/secrets.test.d.ts +2 -0
- package/dist/secrets.test.d.ts.map +1 -0
- package/dist/secrets.test.js +20 -0
- package/dist/secrets.test.js.map +1 -0
- package/dist/shell-env.d.ts +23 -0
- package/dist/shell-env.d.ts.map +1 -0
- package/dist/shell-env.js +34 -0
- package/dist/shell-env.js.map +1 -0
- package/dist/shell-env.test.d.ts +2 -0
- package/dist/shell-env.test.d.ts.map +1 -0
- package/dist/shell-env.test.js +45 -0
- package/dist/shell-env.test.js.map +1 -0
- package/package.json +49 -4
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { HIGH_RISK_PREFIX } from './high-risk.js';
|
|
2
|
+
/**
|
|
3
|
+
* The selection of the policy stack (§21.4).
|
|
4
|
+
*
|
|
5
|
+
* The stack is assembled from the classification of the request, and the
|
|
6
|
+
* assembly is explainable: every module that was selected says why it was
|
|
7
|
+
* selected, so a reader can tell a guardrail that was always on from one
|
|
8
|
+
* that the classifier brought in.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The stack every session gets (§21.4).
|
|
12
|
+
*
|
|
13
|
+
* The list is the one §21.4 names, with `oa.structural-bias` added: the
|
|
14
|
+
* detector of §21.5 is a layer 4 module, and a module that is not in the
|
|
15
|
+
* stack never runs.
|
|
16
|
+
*/
|
|
17
|
+
const BASELINE_POLICY_IDS = [
|
|
18
|
+
'oa.truthfulness-uncertainty',
|
|
19
|
+
'oa.anti-sycophancy',
|
|
20
|
+
'oa.anti-anthropomorphism',
|
|
21
|
+
'oa.anti-dependence',
|
|
22
|
+
'oa.agi-framing',
|
|
23
|
+
'oa.professional-displacement',
|
|
24
|
+
'oa.structural-bias',
|
|
25
|
+
'oa.dark-pattern',
|
|
26
|
+
'oa.scope-enforcement',
|
|
27
|
+
'oa.privacy-transparency',
|
|
28
|
+
'oa.third-party-impact',
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* The stack that is on every tool call (§21.2, layer 1).
|
|
32
|
+
*
|
|
33
|
+
* These are the guardrails that hold whatever the request is: the git
|
|
34
|
+
* hooks, the package manager, the writes, the files a person changes, the
|
|
35
|
+
* decisions a person makes, the secrets and the destructive commands.
|
|
36
|
+
*/
|
|
37
|
+
const ALWAYS_ON_POLICY_IDS = [
|
|
38
|
+
'oa.no-skip-git-hooks',
|
|
39
|
+
'oa.package-manager',
|
|
40
|
+
'oa.workspace-writes-only',
|
|
41
|
+
'oa.protect-policy',
|
|
42
|
+
'oa.human-only-decisions',
|
|
43
|
+
'oa.secret-scan-writes',
|
|
44
|
+
'oa.destructive-needs-approval',
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* The high-risk domain a policy id names, when it names one.
|
|
48
|
+
*
|
|
49
|
+
* The id of a high-risk policy is the domain it guards, so the selection
|
|
50
|
+
* reads the domain off the id rather than off a second list that could
|
|
51
|
+
* disagree with it.
|
|
52
|
+
*/
|
|
53
|
+
function highRiskDomainOf(id) {
|
|
54
|
+
if (!id.startsWith(HIGH_RISK_PREFIX))
|
|
55
|
+
return undefined;
|
|
56
|
+
const domain = id.slice(HIGH_RISK_PREFIX.length);
|
|
57
|
+
return domain.length === 0 ? undefined : domain;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The stack for a classification, and why each module is in it.
|
|
61
|
+
*
|
|
62
|
+
* A module of the always-on list is in every stack. A module of the
|
|
63
|
+
* baseline list is in every stack. A high-risk module is in the stack when
|
|
64
|
+
* the classification named its domain, and a plugin module is in the stack
|
|
65
|
+
* as well: a downstream project that installed a module asked for it to
|
|
66
|
+
* run.
|
|
67
|
+
*/
|
|
68
|
+
export function selectPolicies(modules, classification) {
|
|
69
|
+
const domain = classification.highRiskDomain;
|
|
70
|
+
const selected = [];
|
|
71
|
+
for (const module of modules) {
|
|
72
|
+
if (ALWAYS_ON_POLICY_IDS.includes(module.id)) {
|
|
73
|
+
selected.push({ module, reason: 'the guardrail applies to every tool call' });
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const highRisk = highRiskDomainOf(module.id);
|
|
77
|
+
if (highRisk !== undefined) {
|
|
78
|
+
if (domain !== undefined && domain === highRisk) {
|
|
79
|
+
selected.push({
|
|
80
|
+
module,
|
|
81
|
+
reason: `the classification named the ${highRisk} domain`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const reason = BASELINE_POLICY_IDS.includes(module.id)
|
|
87
|
+
? 'every session gets this policy'
|
|
88
|
+
: 'a plugin brought this policy';
|
|
89
|
+
selected.push({ module, reason });
|
|
90
|
+
}
|
|
91
|
+
return selected;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/policies/selection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAsB;IAC7C,6BAA6B;IAC7B,oBAAoB;IACpB,0BAA0B;IAC1B,oBAAoB;IACpB,gBAAgB;IAChB,8BAA8B;IAC9B,oBAAoB;IACpB,iBAAiB;IACjB,sBAAsB;IACtB,yBAAyB;IACzB,uBAAuB;CACxB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAsB;IAC9C,sBAAsB;IACtB,oBAAoB;IACpB,0BAA0B;IAC1B,mBAAmB;IACnB,yBAAyB;IACzB,uBAAuB;IACvB,+BAA+B;CAChC,CAAC;AAUF;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,EAAU;IAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AAClD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAgC,EAChC,cAAqC;IAErC,MAAM,MAAM,GAAG,cAAc,CAAC,cAAc,CAAC;IAC7C,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,0CAA0C,EAAE,CAAC,CAAC;YAC9E,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAChD,QAAQ,CAAC,IAAI,CAAC;oBACZ,MAAM;oBACN,MAAM,EAAE,gCAAgC,QAAQ,SAAS;iBAC1D,CAAC,CAAC;YACL,CAAC;YACD,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,CAAC,CAAC,gCAAgC;YAClC,CAAC,CAAC,8BAA8B,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type PolicyModule } from '../policy.js';
|
|
2
|
+
/**
|
|
3
|
+
* The structural bias policy (§21.2, §21.5).
|
|
4
|
+
*
|
|
5
|
+
* It flags the defaults and affordances that systematically advantage a
|
|
6
|
+
* privileged user profile: copy that assumes a GPU, English, broadband, a
|
|
7
|
+
* US grid factor, a Mac or a corporate GitHub account. It flags and does not
|
|
8
|
+
* block: the reader decides who the copy is for.
|
|
9
|
+
*/
|
|
10
|
+
/** The stable id of the policy. */
|
|
11
|
+
export declare const STRUCTURAL_BIAS_ID = "oa.structural-bias";
|
|
12
|
+
/** The policy itself. */
|
|
13
|
+
export declare const structuralBias: PolicyModule;
|
|
14
|
+
//# sourceMappingURL=structural-bias.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-bias.d.ts","sourceRoot":"","sources":["../../src/policies/structural-bias.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1E;;;;;;;GAOG;AAEH,mCAAmC;AACnC,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAavD,yBAAyB;AACzB,eAAO,MAAM,cAAc,EAAE,YAc5B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { allow, findingsOf, flag } from '../policy.js';
|
|
2
|
+
import { matches } from './patterns.js';
|
|
3
|
+
/**
|
|
4
|
+
* The structural bias policy (§21.2, §21.5).
|
|
5
|
+
*
|
|
6
|
+
* It flags the defaults and affordances that systematically advantage a
|
|
7
|
+
* privileged user profile: copy that assumes a GPU, English, broadband, a
|
|
8
|
+
* US grid factor, a Mac or a corporate GitHub account. It flags and does not
|
|
9
|
+
* block: the reader decides who the copy is for.
|
|
10
|
+
*/
|
|
11
|
+
/** The stable id of the policy. */
|
|
12
|
+
export const STRUCTURAL_BIAS_ID = 'oa.structural-bias';
|
|
13
|
+
/** The assumptions that leave somebody out. */
|
|
14
|
+
const BIAS = [
|
|
15
|
+
/\b(?:assumes?|assuming|requires?|needs?|expects?)\b[^.]{0,40}\b(?:gpu|cuda|nvidia)\b/gi,
|
|
16
|
+
/\b(?:assumes?|assuming|requires?|needs?|expects?)\b[^.]{0,40}\benglish\b/gi,
|
|
17
|
+
/\b(?:assumes?|assuming|requires?|needs?|expects?)\b[^.]{0,40}\b(?:broadband|fiber|high[- ]speed)\b/gi,
|
|
18
|
+
/\b(?:assumes?|assuming|requires?|needs?|expects?)\b[^.]{0,40}\bus\s+grid\s+factor\b/gi,
|
|
19
|
+
/\b(?:assumes?|assuming|requires?|needs?|expects?)\b[^.]{0,40}\bmac\b/gi,
|
|
20
|
+
/\b(?:assumes?|assuming|requires?|needs?|expects?)\b[^.]{0,40}\b(?:corporate|company|organisation|organization)\s+github\b/gi,
|
|
21
|
+
/\bgithub\s+(?:enterprise|team)\s+account\b/gi,
|
|
22
|
+
];
|
|
23
|
+
/** The policy itself. */
|
|
24
|
+
export const structuralBias = {
|
|
25
|
+
id: STRUCTURAL_BIAS_ID,
|
|
26
|
+
version: '1.0.0',
|
|
27
|
+
layer: 4,
|
|
28
|
+
description: 'Flags defaults and affordances that advantage a privileged user profile.',
|
|
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(BIAS, text);
|
|
36
|
+
if (found.length === 0)
|
|
37
|
+
return allow();
|
|
38
|
+
return flag(findingsOf(STRUCTURAL_BIAS_ID, 'structural-bias', found));
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=structural-bias.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-bias.js","sourceRoot":"","sources":["../../src/policies/structural-bias.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,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,+CAA+C;AAC/C,MAAM,IAAI,GAAG;IACX,wFAAwF;IACxF,4EAA4E;IAC5E,sGAAsG;IACtG,uFAAuF;IACvF,wEAAwE;IACxE,6HAA6H;IAC7H,8CAA8C;CAC/C,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,EAAE,EAAE,kBAAkB;IACtB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,0EAA0E;IACvF,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,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PolicyModule } from '../policy.js';
|
|
2
|
+
/**
|
|
3
|
+
* The third-party impact policy (§21.2).
|
|
4
|
+
*
|
|
5
|
+
* It flags the output that reaches people who are not in the conversation:
|
|
6
|
+
* the users a change lands on, the applicants a score ranks, and the
|
|
7
|
+
* decisions a person is not in the room for. It flags and does not block.
|
|
8
|
+
*/
|
|
9
|
+
/** The stable id of the policy. */
|
|
10
|
+
export declare const THIRD_PARTY_IMPACT_ID = "oa.third-party-impact";
|
|
11
|
+
/** The policy itself. */
|
|
12
|
+
export declare const thirdPartyImpact: PolicyModule;
|
|
13
|
+
//# sourceMappingURL=third-party-impact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"third-party-impact.d.ts","sourceRoot":"","sources":["../../src/policies/third-party-impact.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1E;;;;;;GAMG;AAEH,mCAAmC;AACnC,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAW7D,yBAAyB;AACzB,eAAO,MAAM,gBAAgB,EAAE,YAc9B,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { allow, findingsOf, flag } from '../policy.js';
|
|
2
|
+
import { matches } from './patterns.js';
|
|
3
|
+
/**
|
|
4
|
+
* The third-party impact policy (§21.2).
|
|
5
|
+
*
|
|
6
|
+
* It flags the output that reaches people who are not in the conversation:
|
|
7
|
+
* the users a change lands on, the applicants a score ranks, and the
|
|
8
|
+
* decisions a person is not in the room for. It flags and does not block.
|
|
9
|
+
*/
|
|
10
|
+
/** The stable id of the policy. */
|
|
11
|
+
export const THIRD_PARTY_IMPACT_ID = 'oa.third-party-impact';
|
|
12
|
+
/** The words that reach past the conversation. */
|
|
13
|
+
const THIRD_PARTY = [
|
|
14
|
+
/\b(?:affects|impacts|changes|change)\s+(?:how\s+|the\s+way\s+)?(?:your|the)\s+(?:users|customers|clients|employees|end[- ]users|tenants)\b/gi,
|
|
15
|
+
/\b(?:affects|impacts)\s+(?:other\s+)?(?:users|customers|clients|employees|tenants|third\s+parties|stakeholders)\b/gi,
|
|
16
|
+
/\bwithout\s+(?:their|the\s+user'?s?)\s+(?:knowledge|consent)\b/gi,
|
|
17
|
+
/\b(?:ranks?|scores?|rejects?|approves?)\s+(?:applicants|candidates|tenants|borrowers|employees)\b/gi,
|
|
18
|
+
/\b(?:hiring|lending|criminal\s+justice|public\s+benefits)\s+decisions?\b/gi,
|
|
19
|
+
];
|
|
20
|
+
/** The policy itself. */
|
|
21
|
+
export const thirdPartyImpact = {
|
|
22
|
+
id: THIRD_PARTY_IMPACT_ID,
|
|
23
|
+
version: '1.0.0',
|
|
24
|
+
layer: 4,
|
|
25
|
+
description: 'Flags the output that affects people who are not in the conversation.',
|
|
26
|
+
appliesTo: ['PreResponse'],
|
|
27
|
+
origin: 'first-party',
|
|
28
|
+
evaluate(ctx) {
|
|
29
|
+
const text = ctx.response?.text ?? ctx.request?.text ?? '';
|
|
30
|
+
if (text === '')
|
|
31
|
+
return allow();
|
|
32
|
+
const found = matches(THIRD_PARTY, text);
|
|
33
|
+
if (found.length === 0)
|
|
34
|
+
return allow();
|
|
35
|
+
return flag(findingsOf(THIRD_PARTY_IMPACT_ID, 'third-party-impact', found));
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=third-party-impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"third-party-impact.js","sourceRoot":"","sources":["../../src/policies/third-party-impact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;GAMG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE7D,kDAAkD;AAClD,MAAM,WAAW,GAAG;IAClB,8IAA8I;IAC9I,qHAAqH;IACrH,kEAAkE;IAClE,qGAAqG;IACrG,4EAA4E;CAC7E,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,EAAE,EAAE,qBAAqB;IACzB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,uEAAuE;IACpF,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,WAAW,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9E,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FileChange, PolicyContext } from '../policy.js';
|
|
2
|
+
/**
|
|
3
|
+
* The tool call of a context, read out of it.
|
|
4
|
+
*
|
|
5
|
+
* The context carries the name of the tool and its arguments in the shape
|
|
6
|
+
* the host gave them, so the call is read the way the hook rules read it:
|
|
7
|
+
* the command is the one the arguments name, and the files are the ones the
|
|
8
|
+
* context carries or the arguments name.
|
|
9
|
+
*/
|
|
10
|
+
/** The tool call, as a policy reads it. */
|
|
11
|
+
export interface ToolCallFacts {
|
|
12
|
+
/** The name of the tool. */
|
|
13
|
+
name: string;
|
|
14
|
+
/** The arguments the call was made with. */
|
|
15
|
+
args: Record<string, unknown>;
|
|
16
|
+
/** The command, for a shell call. */
|
|
17
|
+
command?: string | undefined;
|
|
18
|
+
/** The files the call touches. */
|
|
19
|
+
files: FileChange[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The tool call of a context.
|
|
23
|
+
*
|
|
24
|
+
* A context without a tool call has none, and a policy that reads one lets
|
|
25
|
+
* the thing through.
|
|
26
|
+
*/
|
|
27
|
+
export declare function readToolCall(ctx: PolicyContext): ToolCallFacts | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Whether a call writes a file.
|
|
30
|
+
*
|
|
31
|
+
* A tool that is known to write writes; a tool that is known to read does
|
|
32
|
+
* not, even when it names a file. A name that is neither is treated as a
|
|
33
|
+
* writer when the call names a file, because a policy that let an unknown
|
|
34
|
+
* name through would let every write the host names in an unfamiliar way
|
|
35
|
+
* through.
|
|
36
|
+
*/
|
|
37
|
+
export declare function writesFiles(call: ToolCallFacts): boolean;
|
|
38
|
+
//# sourceMappingURL=tool-call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call.d.ts","sourceRoot":"","sources":["../../src/policies/tool-call.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE9D;;;;;;;GAOG;AAEH,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,kCAAkC;IAClC,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAoBD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,GAAG,SAAS,CAY1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAGxD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { isWritingTool } from '../event.js';
|
|
2
|
+
/** The argument names a write tool names its file with. */
|
|
3
|
+
const PATH_ARGS = ['filePath', 'file_path', 'path', 'file'];
|
|
4
|
+
/** The arguments, when they are an object. */
|
|
5
|
+
function argsOf(value) {
|
|
6
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
7
|
+
return {};
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
/** The files the arguments name. */
|
|
11
|
+
function filesFromArgs(args) {
|
|
12
|
+
for (const key of PATH_ARGS) {
|
|
13
|
+
const value = args[key];
|
|
14
|
+
if (typeof value === 'string' && value.length > 0)
|
|
15
|
+
return [{ path: value }];
|
|
16
|
+
}
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The tool call of a context.
|
|
21
|
+
*
|
|
22
|
+
* A context without a tool call has none, and a policy that reads one lets
|
|
23
|
+
* the thing through.
|
|
24
|
+
*/
|
|
25
|
+
export function readToolCall(ctx) {
|
|
26
|
+
const call = ctx.toolCall;
|
|
27
|
+
if (call === undefined)
|
|
28
|
+
return undefined;
|
|
29
|
+
const args = argsOf(call.args);
|
|
30
|
+
const command = args['command'];
|
|
31
|
+
const files = ctx.files !== undefined && ctx.files.length > 0 ? ctx.files : filesFromArgs(args);
|
|
32
|
+
return {
|
|
33
|
+
name: call.name,
|
|
34
|
+
args,
|
|
35
|
+
command: typeof command === 'string' ? command : undefined,
|
|
36
|
+
files,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether a call writes a file.
|
|
41
|
+
*
|
|
42
|
+
* A tool that is known to write writes; a tool that is known to read does
|
|
43
|
+
* not, even when it names a file. A name that is neither is treated as a
|
|
44
|
+
* writer when the call names a file, because a policy that let an unknown
|
|
45
|
+
* name through would let every write the host names in an unfamiliar way
|
|
46
|
+
* through.
|
|
47
|
+
*/
|
|
48
|
+
export function writesFiles(call) {
|
|
49
|
+
if (isWritingTool(call.name))
|
|
50
|
+
return true;
|
|
51
|
+
return call.files.length > 0;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=tool-call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call.js","sourceRoot":"","sources":["../../src/policies/tool-call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwB5C,2DAA2D;AAC3D,MAAM,SAAS,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5D,8CAA8C;AAC9C,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnF,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,oCAAoC;AACpC,SAAS,aAAa,CAAC,IAA6B;IAClD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAkB;IAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC1B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChG,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI;QACJ,OAAO,EAAE,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;QAC1D,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,IAAmB;IAC7C,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PolicyModule } from '../policy.js';
|
|
2
|
+
/**
|
|
3
|
+
* The truthfulness and uncertainty policy (§21.2, layer 3).
|
|
4
|
+
*
|
|
5
|
+
* It is the prompt module of the stack: it asks for the difference between
|
|
6
|
+
* a fact, an inference and a guess to be visible, and it flags the reply
|
|
7
|
+
* that asserts without any sign of doubt when the evidence is thin.
|
|
8
|
+
*/
|
|
9
|
+
/** The stable id of the policy. */
|
|
10
|
+
export declare const TRUTHFULNESS_UNCERTAINTY_ID = "oa.truthfulness-uncertainty";
|
|
11
|
+
/** The policy itself. */
|
|
12
|
+
export declare const truthfulnessUncertainty: PolicyModule;
|
|
13
|
+
//# sourceMappingURL=truthfulness-uncertainty.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truthfulness-uncertainty.d.ts","sourceRoot":"","sources":["../../src/policies/truthfulness-uncertainty.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1E;;;;;;GAMG;AAEH,mCAAmC;AACnC,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAiBzE,yBAAyB;AACzB,eAAO,MAAM,uBAAuB,EAAE,YAgBrC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { allow, findingsOf, flag } from '../policy.js';
|
|
2
|
+
import { matches } from './patterns.js';
|
|
3
|
+
/**
|
|
4
|
+
* The truthfulness and uncertainty policy (§21.2, layer 3).
|
|
5
|
+
*
|
|
6
|
+
* It is the prompt module of the stack: it asks for the difference between
|
|
7
|
+
* a fact, an inference and a guess to be visible, and it flags the reply
|
|
8
|
+
* that asserts without any sign of doubt when the evidence is thin.
|
|
9
|
+
*/
|
|
10
|
+
/** The stable id of the policy. */
|
|
11
|
+
export const TRUTHFULNESS_UNCERTAINTY_ID = 'oa.truthfulness-uncertainty';
|
|
12
|
+
/** The words that claim more than the evidence carries. */
|
|
13
|
+
const CERTAIN = [
|
|
14
|
+
/\b(?:definitely|certainly|guaranteed|without\s+doubt|100%\s+certain)\b/gi,
|
|
15
|
+
/\b(?:always|never)\s+(?:the\s+)?(?:case|true|right|wrong)\b/gi,
|
|
16
|
+
];
|
|
17
|
+
/** The words that mark an inference or a guess as one. */
|
|
18
|
+
const DOUBT = [
|
|
19
|
+
/\b(?:probably|likely|unlikely|perhaps|maybe|possibly|apparently)\b/gi,
|
|
20
|
+
/\b(?:i\s+think|i\s+believe|it\s+seems|it\s+appears|as\s+far\s+as\s+i\s+can\s+tell)\b/gi,
|
|
21
|
+
/\b(?:unclear|uncertain|not\s+sure|cannot\s+be\s+sure)\b/gi,
|
|
22
|
+
/\b(?:roughly|approximately|about\s+\d)\b/gi,
|
|
23
|
+
/\b(?:may|might|could)\s+(?:be|have|not)\b/gi,
|
|
24
|
+
];
|
|
25
|
+
/** The policy itself. */
|
|
26
|
+
export const truthfulnessUncertainty = {
|
|
27
|
+
id: TRUTHFULNESS_UNCERTAINTY_ID,
|
|
28
|
+
version: '1.0.0',
|
|
29
|
+
layer: 3,
|
|
30
|
+
description: 'Asks for facts, inferences and guesses to be told apart, and flags certainty without doubt.',
|
|
31
|
+
appliesTo: ['UserPromptSubmit', 'PreResponse'],
|
|
32
|
+
origin: 'first-party',
|
|
33
|
+
evaluate(ctx) {
|
|
34
|
+
const text = ctx.response?.text ?? ctx.request?.text ?? '';
|
|
35
|
+
if (text === '')
|
|
36
|
+
return allow();
|
|
37
|
+
const certain = matches(CERTAIN, text);
|
|
38
|
+
if (certain.length === 0)
|
|
39
|
+
return allow();
|
|
40
|
+
if (matches(DOUBT, text).length > 0)
|
|
41
|
+
return allow();
|
|
42
|
+
return flag(findingsOf(TRUTHFULNESS_UNCERTAINTY_ID, 'certainty', certain));
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=truthfulness-uncertainty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truthfulness-uncertainty.js","sourceRoot":"","sources":["../../src/policies/truthfulness-uncertainty.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;GAMG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,2BAA2B,GAAG,6BAA6B,CAAC;AAEzE,2DAA2D;AAC3D,MAAM,OAAO,GAAG;IACd,0EAA0E;IAC1E,+DAA+D;CAChE,CAAC;AAEF,0DAA0D;AAC1D,MAAM,KAAK,GAAG;IACZ,sEAAsE;IACtE,wFAAwF;IACxF,2DAA2D;IAC3D,4CAA4C;IAC5C,6CAA6C;CAC9C,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,uBAAuB,GAAiB;IACnD,EAAE,EAAE,2BAA2B;IAC/B,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,CAAC;IACR,WAAW,EACT,6FAA6F;IAC/F,SAAS,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC;IAC9C,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,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC,UAAU,CAAC,2BAA2B,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7E,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type PolicyModule } from '../policy.js';
|
|
2
|
+
/**
|
|
3
|
+
* The workspace-writes-only policy (§21.2, layer 1).
|
|
4
|
+
*
|
|
5
|
+
* It blocks a write outside the workspace and outside the OpenAgentsy
|
|
6
|
+
* worktrees of the same project. The policy is built with the workspace it
|
|
7
|
+
* guards, because the roots are what the decision is made against.
|
|
8
|
+
*/
|
|
9
|
+
/** The stable id of the policy. */
|
|
10
|
+
export declare const WORKSPACE_WRITES_ONLY_ID = "oa.workspace-writes-only";
|
|
11
|
+
/** What the policy is built with. */
|
|
12
|
+
export interface WorkspaceWritesOnlyOptions {
|
|
13
|
+
/** The workspace root: the project the agent works in. */
|
|
14
|
+
workspace: string;
|
|
15
|
+
/** The home directory the worktrees live under; the home of the user by default. */
|
|
16
|
+
home?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The policy itself.
|
|
20
|
+
*
|
|
21
|
+
* The roots are the workspace and the worktrees of the same project, and a
|
|
22
|
+
* write that lands outside both of them is the one that is blocked.
|
|
23
|
+
*/
|
|
24
|
+
export declare function workspaceWritesOnly(options: WorkspaceWritesOnlyOptions): PolicyModule;
|
|
25
|
+
//# sourceMappingURL=workspace-writes-only.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-writes-only.d.ts","sourceRoot":"","sources":["../../src/policies/workspace-writes-only.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG/D;;;;;;GAMG;AAEH,mCAAmC;AACnC,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE,qCAAqC;AACrC,MAAM,WAAW,0BAA0B;IACzC,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAYD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,YAAY,CAuBrF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
2
|
+
import { isInside, projectName, worktreeRoot } from '../paths.js';
|
|
3
|
+
import { allow, block } from '../policy.js';
|
|
4
|
+
import { readToolCall, writesFiles } from './tool-call.js';
|
|
5
|
+
/**
|
|
6
|
+
* The workspace-writes-only policy (§21.2, layer 1).
|
|
7
|
+
*
|
|
8
|
+
* It blocks a write outside the workspace and outside the OpenAgentsy
|
|
9
|
+
* worktrees of the same project. The policy is built with the workspace it
|
|
10
|
+
* guards, because the roots are what the decision is made against.
|
|
11
|
+
*/
|
|
12
|
+
/** The stable id of the policy. */
|
|
13
|
+
export const WORKSPACE_WRITES_ONLY_ID = 'oa.workspace-writes-only';
|
|
14
|
+
/**
|
|
15
|
+
* A path, made absolute against the workspace.
|
|
16
|
+
*
|
|
17
|
+
* A host names a file either way, and a relative path is relative to the
|
|
18
|
+
* project the agent works in.
|
|
19
|
+
*/
|
|
20
|
+
function absolutePath(root, path) {
|
|
21
|
+
return isAbsolute(path) ? path : resolve(root, path);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The policy itself.
|
|
25
|
+
*
|
|
26
|
+
* The roots are the workspace and the worktrees of the same project, and a
|
|
27
|
+
* write that lands outside both of them is the one that is blocked.
|
|
28
|
+
*/
|
|
29
|
+
export function workspaceWritesOnly(options) {
|
|
30
|
+
const root = resolve(options.workspace);
|
|
31
|
+
const roots = [root, worktreeRoot(projectName(root), options.home)];
|
|
32
|
+
return {
|
|
33
|
+
id: WORKSPACE_WRITES_ONLY_ID,
|
|
34
|
+
version: '1.0.0',
|
|
35
|
+
layer: 1,
|
|
36
|
+
description: 'Blocks the writes that land outside the workspace and the worktrees.',
|
|
37
|
+
appliesTo: ['PreToolCall'],
|
|
38
|
+
origin: 'first-party',
|
|
39
|
+
evaluate(ctx) {
|
|
40
|
+
const call = readToolCall(ctx);
|
|
41
|
+
if (call === undefined)
|
|
42
|
+
return allow();
|
|
43
|
+
if (!writesFiles(call))
|
|
44
|
+
return allow();
|
|
45
|
+
const outside = call.files.some((file) => [file.path, file.fromPath]
|
|
46
|
+
.filter((path) => path !== undefined)
|
|
47
|
+
.some((path) => !isInside(absolutePath(root, path), roots)));
|
|
48
|
+
if (!outside)
|
|
49
|
+
return allow();
|
|
50
|
+
return block('Writes are limited to the workspace and OpenAgentsy worktrees.');
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=workspace-writes-only.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-writes-only.js","sourceRoot":"","sources":["../../src/policies/workspace-writes-only.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAqB,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE3D;;;;;;GAMG;AAEH,mCAAmC;AACnC,MAAM,CAAC,MAAM,wBAAwB,GAAG,0BAA0B,CAAC;AAUnE;;;;;GAKG;AACH,SAAS,YAAY,CAAC,IAAY,EAAE,IAAY;IAC9C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,OAAO;QACL,EAAE,EAAE,wBAAwB;QAC5B,OAAO,EAAE,OAAO;QAChB,KAAK,EAAE,CAAC;QACR,WAAW,EAAE,sEAAsE;QACnF,SAAS,EAAE,CAAC,aAAa,CAAC;QAC1B,MAAM,EAAE,aAAa;QACrB,QAAQ,CAAC,GAAG;YACV,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,EAAE,CAAC;YACvC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACvC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC;iBACvB,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC;iBACpD,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAC9D,CAAC;YACF,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACjF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { PolicyFiringSink } from '@openagentsy/core';
|
|
2
|
+
import type { PolicyContext, PolicyModule, PolicyMoment, PolicyOutcome, PolicyResult } from './policy.js';
|
|
3
|
+
import type { PolicyRegistry } from './policy-registry.js';
|
|
4
|
+
/**
|
|
5
|
+
* The policy engine (§21.3).
|
|
6
|
+
*
|
|
7
|
+
* The engine asks the stack for a decision and records what it decided. The
|
|
8
|
+
* record carries the id of the policy, the version it had at that moment,
|
|
9
|
+
* the session and the outcome, so a regression is attributed to the version
|
|
10
|
+
* that caused it.
|
|
11
|
+
*
|
|
12
|
+
* The engine writes through a sink and knows nothing of any store, so the
|
|
13
|
+
* log is the caller's choice: the ledger is the one the plan names, and the
|
|
14
|
+
* rows survive a restart because they are rows in a database and not words
|
|
15
|
+
* in a process.
|
|
16
|
+
*/
|
|
17
|
+
/** The id of the row that records the assembled stack. */
|
|
18
|
+
export declare const STACK_POLICY_ID = "oa.policy.stack";
|
|
19
|
+
/** The version of the stack row. */
|
|
20
|
+
export declare const STACK_POLICY_VERSION = "1.0.0";
|
|
21
|
+
/** What the engine is built with. */
|
|
22
|
+
export interface PolicyEngineOptions {
|
|
23
|
+
/** Where the firings go; an engine without one records nothing. */
|
|
24
|
+
sink?: PolicyFiringSink | undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The moment a context is about.
|
|
28
|
+
*
|
|
29
|
+
* A context with a tool call is about the call, one with a response is
|
|
30
|
+
* about the reply, and one with a request is about the request. A context
|
|
31
|
+
* with none of them is about nothing, and no policy runs.
|
|
32
|
+
*/
|
|
33
|
+
export declare function momentOf(ctx: PolicyContext): PolicyMoment | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* A decision, as the engine reports it.
|
|
36
|
+
*
|
|
37
|
+
* A decision that allowed the thing through carries no findings, and a
|
|
38
|
+
* decision that flagged carries the severity of the flag.
|
|
39
|
+
*/
|
|
40
|
+
export declare function outcomeOf(module: PolicyModule, result: PolicyResult): PolicyOutcome;
|
|
41
|
+
/** The engine of a registry. */
|
|
42
|
+
export declare class PolicyEngine {
|
|
43
|
+
/** The registry the stack comes from. */
|
|
44
|
+
private readonly registry;
|
|
45
|
+
/** Where the firings go. */
|
|
46
|
+
private readonly sink;
|
|
47
|
+
/** The sessions whose stack was already recorded. */
|
|
48
|
+
private readonly assembled;
|
|
49
|
+
/**
|
|
50
|
+
* An engine of a registry.
|
|
51
|
+
*
|
|
52
|
+
* The engine holds no state beyond the sessions whose stack it recorded,
|
|
53
|
+
* so it may be built once for a session and used for every call in it.
|
|
54
|
+
*/
|
|
55
|
+
constructor(registry: PolicyRegistry, options?: PolicyEngineOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Ask the stack, and record what it decided.
|
|
58
|
+
*
|
|
59
|
+
* The stack is recorded once per session: the first row of the session
|
|
60
|
+
* carries the whole stack, so a reader can see what the session was
|
|
61
|
+
* guarded by without reading every row.
|
|
62
|
+
*/
|
|
63
|
+
evaluate(ctx: PolicyContext): PolicyOutcome[];
|
|
64
|
+
/** The row that records the stack of a session. */
|
|
65
|
+
private recordStack;
|
|
66
|
+
/** The row that records one decision. */
|
|
67
|
+
private record;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=policy-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../src/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,sBAAsB,CAAC;AAE5E;;;;;;;;;;;;GAYG;AAEH,0DAA0D;AAC1D,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD,oCAAoC;AACpC,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,IAAI,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,SAAS,CAKrE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,aAAa,CAiBnF;AAED,gCAAgC;AAChC,qBAAa,YAAY;IACvB,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,4BAA4B;IAC5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA+B;IACpD,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD;;;;;OAKG;gBACS,QAAQ,EAAE,cAAc,EAAE,OAAO,GAAE,mBAAwB;IAKvE;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,EAAE;IAkB7C,mDAAmD;IACnD,OAAO,CAAC,WAAW;IAqBnB,yCAAyC;IACzC,OAAO,CAAC,MAAM;CAkBf"}
|