@occasiolabs/occasio 0.8.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.
Files changed (92) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +10 -0
  3. package/README.md +216 -0
  4. package/bin/occasio-mcp.js +5 -0
  5. package/bin/occasio.js +2 -0
  6. package/bin/supervisor/README.md +90 -0
  7. package/bin/supervisor/com.occasio.proxy.plist.template +36 -0
  8. package/bin/supervisor/install-windows-task.ps1 +48 -0
  9. package/bin/supervisor/occasio.service +18 -0
  10. package/docs/AUDIT.md +120 -0
  11. package/docs/attest_verify.py +283 -0
  12. package/docs/audit_walker.py +65 -0
  13. package/docs/canonicalize.py +99 -0
  14. package/docs/compliance-mapping.md +93 -0
  15. package/docs/demos/mcp-block.md +148 -0
  16. package/docs/edr-calibration.md +73 -0
  17. package/docs/edr-demo.md +83 -0
  18. package/docs/python-verifier.md +74 -0
  19. package/docs/reference-pipeline.md +140 -0
  20. package/package.json +69 -0
  21. package/policy-templates/dev-default.yml +84 -0
  22. package/policy-templates/finance.yml +61 -0
  23. package/policy-templates/strict.yml +49 -0
  24. package/schemas/agent-attestation-v1.json +190 -0
  25. package/schemas/occasio-policy.schema.json +99 -0
  26. package/spec/agent-attestation/v1/README.md +137 -0
  27. package/src/adapters/claude-code.js +518 -0
  28. package/src/adapters/cline.js +161 -0
  29. package/src/adapters/computer-use-cli.js +198 -0
  30. package/src/adapters/computer-use.js +227 -0
  31. package/src/analyzer.js +170 -0
  32. package/src/anomaly/cli.js +143 -0
  33. package/src/anomaly/detectors/deny-rate.js +84 -0
  34. package/src/anomaly/detectors/file-read-volume.js +109 -0
  35. package/src/anomaly/detectors/secret-redact-rate.js +107 -0
  36. package/src/anomaly/detectors/unknown-tool-input.js +83 -0
  37. package/src/anomaly/index.js +169 -0
  38. package/src/attest/canonicalize.js +97 -0
  39. package/src/attest/index.js +355 -0
  40. package/src/attest/run-slice.js +57 -0
  41. package/src/attest/sign.js +186 -0
  42. package/src/attest/verify.js +192 -0
  43. package/src/audit/errors.js +21 -0
  44. package/src/audit/input-normalizer.js +121 -0
  45. package/src/audit/jsonl-auditor.js +178 -0
  46. package/src/audit/verifier.js +152 -0
  47. package/src/baseline.js +507 -0
  48. package/src/boundary.js +238 -0
  49. package/src/budget.js +42 -0
  50. package/src/classifier.js +115 -0
  51. package/src/context-budget.js +77 -0
  52. package/src/core/boundary-event.js +75 -0
  53. package/src/core/decision.js +61 -0
  54. package/src/core/pipeline.js +66 -0
  55. package/src/core/tool-names.js +105 -0
  56. package/src/dashboard.js +892 -0
  57. package/src/demo/README.md +31 -0
  58. package/src/demo/anomalies-demo.js +211 -0
  59. package/src/demo/attest-demo.js +198 -0
  60. package/src/distiller.js +155 -0
  61. package/src/embeddings.json +72 -0
  62. package/src/executor/dispatcher.js +230 -0
  63. package/src/harness.js +817 -0
  64. package/src/index.js +1711 -0
  65. package/src/inspect.js +329 -0
  66. package/src/interceptor.js +1198 -0
  67. package/src/lao.js +185 -0
  68. package/src/lao_prep.py +119 -0
  69. package/src/ledger.js +209 -0
  70. package/src/mcp-experiment.js +140 -0
  71. package/src/mcp-normalize.js +139 -0
  72. package/src/mcp-server.js +320 -0
  73. package/src/outbound-policy.js +433 -0
  74. package/src/policy/built-in-classifiers.js +78 -0
  75. package/src/policy/doctor.js +226 -0
  76. package/src/policy/engine.js +339 -0
  77. package/src/policy/init.js +153 -0
  78. package/src/policy/loader.js +448 -0
  79. package/src/policy/rules-default.js +36 -0
  80. package/src/policy/shell-path.js +135 -0
  81. package/src/policy/show.js +196 -0
  82. package/src/policy/validate.js +310 -0
  83. package/src/preflight/cli.js +164 -0
  84. package/src/preflight/miner.js +329 -0
  85. package/src/proxy/agent-router.js +93 -0
  86. package/src/redteam.js +428 -0
  87. package/src/replay.js +446 -0
  88. package/src/report/index.js +224 -0
  89. package/src/runtime.js +595 -0
  90. package/src/scanner/index.js +49 -0
  91. package/src/selftest.js +192 -0
  92. package/src/session.js +36 -0
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Canonical tool-name registry — the vocabulary of tools the boundary layer
5
+ * recognizes, independent of any specific AI agent's protocol naming.
6
+ *
7
+ * Each adapter (claude-code, future cline, future cursor) maps its own
8
+ * agent-specific tool names to canonical names. Inside the pipeline —
9
+ * BoundaryEvent.toolName, dispatcher.NATIVE_HANDLERS, policy.tools — only
10
+ * canonical names appear. Agent-specific names live in the adapter and in
11
+ * the BoundaryEvent.raw payload.
12
+ *
13
+ * Stage 3 canonical names mirror MCP / common-sense conventions where
14
+ * applicable (read_file, find_files, grep). Stage 4+ may add more.
15
+ */
16
+
17
+ const CANONICAL = Object.freeze({
18
+ READ_FILE: 'read_file',
19
+ FIND_FILES: 'find_files',
20
+ GREP: 'grep',
21
+ TODO_WRITE: 'todo_write',
22
+ TODO_READ: 'todo_read',
23
+ SHELL_BASH: 'shell_bash',
24
+ SHELL_POWERSHELL: 'shell_powershell',
25
+ });
26
+
27
+ const CANONICAL_NAMES = new Set(Object.values(CANONICAL));
28
+
29
+ // agentId → { agentToolName: canonicalName, ... }
30
+ const _agentMaps = {};
31
+
32
+ /**
33
+ * Register an agent's name map. Called at adapter module load.
34
+ * @param {string} agentId e.g., 'claude-code'
35
+ * @param {object} nameMap keys = agent's tool names, values = canonical names
36
+ */
37
+ function register(agentId, nameMap) {
38
+ if (typeof agentId !== 'string' || !agentId) throw new Error('register: agentId required');
39
+ if (!nameMap || typeof nameMap !== 'object') throw new Error('register: nameMap object required');
40
+ const entry = {};
41
+ for (const k of Object.keys(nameMap)) {
42
+ const canonical = nameMap[k];
43
+ if (!CANONICAL_NAMES.has(canonical)) {
44
+ throw new Error(`register: ${agentId}.${k} maps to unknown canonical "${canonical}"`);
45
+ }
46
+ entry[k] = canonical;
47
+ }
48
+ _agentMaps[agentId] = entry;
49
+ }
50
+
51
+ /**
52
+ * Translate one agent's tool name to its canonical name, if registered.
53
+ * Returns null if the agent or name is unknown.
54
+ */
55
+ function toCanonical(agentId, agentName) {
56
+ const map = _agentMaps[agentId];
57
+ return (map && map[agentName]) || null;
58
+ }
59
+
60
+ /**
61
+ * Reverse: translate a canonical name back to a given agent's tool name.
62
+ * Returns null if the agent or canonical is unknown to that agent.
63
+ */
64
+ function toAgentName(agentId, canonicalName) {
65
+ const map = _agentMaps[agentId];
66
+ if (!map) return null;
67
+ for (const k of Object.keys(map)) {
68
+ if (map[k] === canonicalName) return k;
69
+ }
70
+ return null;
71
+ }
72
+
73
+ /**
74
+ * Look up the canonical name across ALL registered agents. First match wins.
75
+ * Used at policy-load time to translate `Read:` (Claude name) → `read_file`
76
+ * so users who paste agent-native names in policy.yml still resolve correctly.
77
+ *
78
+ * Returns null if no agent has the name in its map.
79
+ */
80
+ function firstCanonicalFor(name) {
81
+ for (const agentId of Object.keys(_agentMaps)) {
82
+ if (_agentMaps[agentId][name]) return _agentMaps[agentId][name];
83
+ }
84
+ return null;
85
+ }
86
+
87
+ function isCanonical(name) {
88
+ return CANONICAL_NAMES.has(name);
89
+ }
90
+
91
+ /** Test helper: clear all registered agents. */
92
+ function _resetForTests() {
93
+ for (const k of Object.keys(_agentMaps)) delete _agentMaps[k];
94
+ }
95
+
96
+ module.exports = {
97
+ CANONICAL,
98
+ CANONICAL_NAMES,
99
+ register,
100
+ toCanonical,
101
+ toAgentName,
102
+ firstCanonicalFor,
103
+ isCanonical,
104
+ _resetForTests,
105
+ };