@mseep/open-computer-use 1.0.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 (769) hide show
  1. package/.coderabbit.yaml +25 -0
  2. package/.dockerignore +95 -0
  3. package/.env.example +137 -0
  4. package/.githooks/pre-commit +68 -0
  5. package/.github/CODEOWNERS +125 -0
  6. package/.github/ISSUE_TEMPLATE/adr-proposal.md +41 -0
  7. package/.github/ISSUE_TEMPLATE/bug-report.md +49 -0
  8. package/.github/ISSUE_TEMPLATE/component-proposal.md +38 -0
  9. package/.github/ISSUE_TEMPLATE/config.yml +15 -0
  10. package/.github/ISSUE_TEMPLATE/dependency-proposal.md +59 -0
  11. package/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
  12. package/.github/ISSUE_TEMPLATE/nfr-proposal.md +44 -0
  13. package/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  14. package/.github/codeql/codeql-config.yml +11 -0
  15. package/.github/codeql/extensions/security-models/python-sanitizers.model.yml +17 -0
  16. package/.github/codeql/extensions/security-models/qlpack.yml +7 -0
  17. package/.github/dependabot.yml +23 -0
  18. package/.github/security-exceptions.yml +23 -0
  19. package/.github/workflows/build.yml +420 -0
  20. package/.github/workflows/codeql.yml +33 -0
  21. package/.github/workflows/contracts-lint.yml +90 -0
  22. package/.github/workflows/docs-lint.yml +151 -0
  23. package/.github/workflows/helm.yml +131 -0
  24. package/.github/workflows/identity-lint.yml +30 -0
  25. package/.github/workflows/release-chart.yml +177 -0
  26. package/.github/workflows/release.yml +95 -0
  27. package/.github/workflows/security.yml +332 -0
  28. package/.github/workflows/stale.yml +31 -0
  29. package/.github/workflows/supply-chain.yml +242 -0
  30. package/.gitleaks.toml +53 -0
  31. package/.markdownlint.yaml +51 -0
  32. package/.semgrepignore +85 -0
  33. package/.vale/styles/Architecture/ap13-data-class-substrate.yml +12 -0
  34. package/.vale/styles/Architecture/banned-phrases.yml +23 -0
  35. package/.vale/styles/Architecture/banned-vocab.yml +23 -0
  36. package/.vale/styles/Architecture/marketing-tone.yml +19 -0
  37. package/.vale.ini +18 -0
  38. package/CHANGELOG.md +411 -0
  39. package/CLAUDE.md +218 -0
  40. package/CONTRIBUTING.md +82 -0
  41. package/Dockerfile +676 -0
  42. package/LICENSE +98 -0
  43. package/LICENSE-APACHE +202 -0
  44. package/LICENSE-MIT +21 -0
  45. package/NOTICE +36 -0
  46. package/README.md +516 -0
  47. package/SECURITY.md +45 -0
  48. package/THIRD-PARTY-LICENSES.md +14 -0
  49. package/apt-packages.txt +108 -0
  50. package/computer-use-server/.dockerignore +13 -0
  51. package/computer-use-server/Dockerfile +44 -0
  52. package/computer-use-server/README.md +84 -0
  53. package/computer-use-server/app.py +1544 -0
  54. package/computer-use-server/bin/list-subagent-models +449 -0
  55. package/computer-use-server/cli-defaults/README.md +31 -0
  56. package/computer-use-server/cli-defaults/codex.json +7 -0
  57. package/computer-use-server/cli-defaults/opencode.json +18 -0
  58. package/computer-use-server/cli_adapters/__init__.py +46 -0
  59. package/computer-use-server/cli_adapters/claude.py +163 -0
  60. package/computer-use-server/cli_adapters/codex.py +163 -0
  61. package/computer-use-server/cli_adapters/opencode.py +169 -0
  62. package/computer-use-server/cli_adapters/result.py +34 -0
  63. package/computer-use-server/cli_runtime.py +316 -0
  64. package/computer-use-server/context_vars.py +24 -0
  65. package/computer-use-server/docker_manager.py +1100 -0
  66. package/computer-use-server/docs_html.py +12 -0
  67. package/computer-use-server/mcp_resources.py +170 -0
  68. package/computer-use-server/mcp_tools.py +1430 -0
  69. package/computer-use-server/requirements.txt +17 -0
  70. package/computer-use-server/security.py +50 -0
  71. package/computer-use-server/skill_manager.py +664 -0
  72. package/computer-use-server/static/browser-viewer.js +445 -0
  73. package/computer-use-server/static/chart.umd.js +14 -0
  74. package/computer-use-server/static/docs.html +203 -0
  75. package/computer-use-server/static/github-dark.min.css +10 -0
  76. package/computer-use-server/static/github.min.css +10 -0
  77. package/computer-use-server/static/highlight.min.js +1213 -0
  78. package/computer-use-server/static/highlightjs-line-numbers.min.js +1 -0
  79. package/computer-use-server/static/icons.js +74 -0
  80. package/computer-use-server/static/jszip.min.js +13 -0
  81. package/computer-use-server/static/katex/auto-render.min.js +1 -0
  82. package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.ttf +0 -0
  83. package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.woff +0 -0
  84. package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  85. package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  86. package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  87. package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  88. package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  89. package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  90. package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  91. package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  92. package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  93. package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  94. package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  95. package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  96. package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  97. package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.ttf +0 -0
  98. package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.woff +0 -0
  99. package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  100. package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  101. package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  102. package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  103. package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.ttf +0 -0
  104. package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.woff +0 -0
  105. package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  106. package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.ttf +0 -0
  107. package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.woff +0 -0
  108. package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  109. package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  110. package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  111. package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  112. package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.ttf +0 -0
  113. package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.woff +0 -0
  114. package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  115. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  116. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  117. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  118. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  119. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  120. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  121. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  122. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  123. package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  124. package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.ttf +0 -0
  125. package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.woff +0 -0
  126. package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  127. package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.ttf +0 -0
  128. package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.woff +0 -0
  129. package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  130. package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.ttf +0 -0
  131. package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.woff +0 -0
  132. package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  133. package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.ttf +0 -0
  134. package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.woff +0 -0
  135. package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  136. package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.ttf +0 -0
  137. package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.woff +0 -0
  138. package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  139. package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  140. package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  141. package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  142. package/computer-use-server/static/katex/katex.min.css +1 -0
  143. package/computer-use-server/static/katex/katex.min.js +1 -0
  144. package/computer-use-server/static/locale.js +242 -0
  145. package/computer-use-server/static/mammoth.browser.min.js +21 -0
  146. package/computer-use-server/static/marked.min.js +6 -0
  147. package/computer-use-server/static/mermaid.min.js +2811 -0
  148. package/computer-use-server/static/pdf.min.js +22 -0
  149. package/computer-use-server/static/pdf.worker.min.js +22 -0
  150. package/computer-use-server/static/pptxviewjs.min.js +1 -0
  151. package/computer-use-server/static/preact-htm.min.js +1 -0
  152. package/computer-use-server/static/preview.css +1030 -0
  153. package/computer-use-server/static/preview.js +1522 -0
  154. package/computer-use-server/static/xlsx.full.min.js +22 -0
  155. package/computer-use-server/static/xterm-addon-fit.min.js +2 -0
  156. package/computer-use-server/static/xterm-addon-web-links.min.js +2 -0
  157. package/computer-use-server/static/xterm.css +218 -0
  158. package/computer-use-server/static/xterm.min.js +2 -0
  159. package/computer-use-server/system_prompt.py +761 -0
  160. package/computer-use-server/uploads.py +82 -0
  161. package/contracts/README.md +53 -0
  162. package/contracts/audit/audit-fanin.asyncapi.yaml +407 -0
  163. package/contracts/exec/exec-channel.schema.json +240 -0
  164. package/contracts/mcp/2025-06-18/ocu-constraints.schema.json +178 -0
  165. package/contracts/storage/file-artifact-api.schema.json +390 -0
  166. package/contracts/storage/file-ops.schema.json +217 -0
  167. package/contracts/storage/mount-config.schema.json +197 -0
  168. package/cron/Dockerfile +15 -0
  169. package/cron/cleanup-quick.sh +21 -0
  170. package/cron/cleanup.sh +127 -0
  171. package/data/outputs/.gitkeep +0 -0
  172. package/data/uploads/.gitkeep +0 -0
  173. package/docker-compose.test.yml +54 -0
  174. package/docker-compose.webui.yml +77 -0
  175. package/docker-compose.yml +96 -0
  176. package/docs/CLOUD.md +29 -0
  177. package/docs/COMPARISON.md +128 -0
  178. package/docs/DOCKER.md +469 -0
  179. package/docs/DYNAMIC-SKILLS.md +77 -0
  180. package/docs/FEATURES.md +100 -0
  181. package/docs/INSTALL.md +111 -0
  182. package/docs/KNOWN-BUGS.md +86 -0
  183. package/docs/MCP.md +320 -0
  184. package/docs/SCREENSHOTS.md +39 -0
  185. package/docs/SKILLS-USER-GUIDE.md +86 -0
  186. package/docs/SKILLS.md +483 -0
  187. package/docs/TERMINAL-TAB.md +56 -0
  188. package/docs/architecture/02-trust-boundaries.md +224 -0
  189. package/docs/architecture/03-c4-context.md +61 -0
  190. package/docs/architecture/04-bounded-contexts.md +119 -0
  191. package/docs/architecture/05-c4-container.md +88 -0
  192. package/docs/architecture/06-threat-model.md +172 -0
  193. package/docs/architecture/08-contracts.md +105 -0
  194. package/docs/architecture/MANIFESTO.md +38 -0
  195. package/docs/architecture/PROCESS.md +64 -0
  196. package/docs/architecture/README.md +37 -0
  197. package/docs/architecture/adr/0000-template.md +65 -0
  198. package/docs/architecture/adr/0001-layer-0-gate-legacy-exclusion.md +75 -0
  199. package/docs/architecture/adr/0002-session-view-descriptor.md +57 -0
  200. package/docs/architecture/adr/0003-sandbox-runtime-tier-ladder.md +63 -0
  201. package/docs/architecture/adr/0004-operator-authentication-substrate.md +63 -0
  202. package/docs/architecture/adr/0005-egress-credential-delivery-envoy-sds.md +62 -0
  203. package/docs/architecture/adr/0006-egress-forward-proxy-substrate.md +65 -0
  204. package/docs/architecture/adr/0007-egress-auth-mechanism.md +72 -0
  205. package/docs/architecture/adr/0008-session-egress-attribution.md +59 -0
  206. package/docs/architecture/adr/0009-audit-pipeline-pluggable-by-contract.md +76 -0
  207. package/docs/architecture/adr/0010-storage-backend-pluggable-adapter.md +60 -0
  208. package/docs/architecture/adr/0011-storage-egress-lane.md +67 -0
  209. package/docs/architecture/adr/0012-implementation-language.md +67 -0
  210. package/docs/architecture/adr/0020-sandbox-image-provisioning.md +82 -0
  211. package/docs/architecture/adr/README.md +53 -0
  212. package/docs/architecture/compliance/.gitkeep +0 -0
  213. package/docs/architecture/components/00-overview.md +42 -0
  214. package/docs/architecture/components/0000-template.md +50 -0
  215. package/docs/architecture/components/01-mcp-gateway.md +80 -0
  216. package/docs/architecture/components/02-control-operator-api.md +80 -0
  217. package/docs/architecture/components/04-storage-broker.md +104 -0
  218. package/docs/architecture/components/05-session-sandbox.md +93 -0
  219. package/docs/architecture/components/06-egress-trust-edge.md +95 -0
  220. package/docs/architecture/components/07-audit-pipeline.md +110 -0
  221. package/docs/architecture/diagrams/.gitkeep +0 -0
  222. package/docs/architecture/diagrams/02-trust-boundaries.mmd +111 -0
  223. package/docs/architecture/diagrams/06-threat-model.mmd +41 -0
  224. package/docs/architecture/diagrams/08-contracts.mmd +47 -0
  225. package/docs/architecture/diagrams/c4-container.mmd +59 -0
  226. package/docs/architecture/diagrams/c4-context.mmd +46 -0
  227. package/docs/architecture/glossary.md +172 -0
  228. package/docs/architecture/manifesto/.gitkeep +0 -0
  229. package/docs/architecture/manifesto/01-audience-and-buyer.md +57 -0
  230. package/docs/architecture/manifesto/02-nfrs.md +325 -0
  231. package/docs/architecture/manifesto/03-non-negotiables.md +35 -0
  232. package/docs/architecture/manifesto/04-non-goals.md +23 -0
  233. package/docs/architecture/manifesto/05-licensing-posture.md +61 -0
  234. package/docs/architecture/manifesto/06-starter-mode-policy.md +49 -0
  235. package/docs/architecture/manifesto/07-governance.md +60 -0
  236. package/docs/architecture/primitives-backlog.md +51 -0
  237. package/docs/architecture.svg +117 -0
  238. package/docs/claude-code-gateway.md +173 -0
  239. package/docs/cli-config-templates.md +240 -0
  240. package/docs/data-flow.svg +72 -0
  241. package/docs/demo-landing-page.gif +0 -0
  242. package/docs/demo-qwen-trending.gif +0 -0
  243. package/docs/dynamic-skills.svg +77 -0
  244. package/docs/file-flow.svg +126 -0
  245. package/docs/future-architecture/README.md +152 -0
  246. package/docs/future-architecture/adr/0001-control-plane-language-go.md +80 -0
  247. package/docs/future-architecture/adr/0002-guest-agent-language-go.md +84 -0
  248. package/docs/future-architecture/adr/0003-docker-poc-first-then-k8s.md +37 -0
  249. package/docs/future-architecture/adr/0004-pluggable-runtime-via-runtimeclass.md +34 -0
  250. package/docs/future-architecture/adr/0005-mcp-as-control-plane-gateway.md +34 -0
  251. package/docs/future-architecture/adr/0006-no-agpl-no-bsl-dependencies.md +41 -0
  252. package/docs/future-architecture/adr/0007-superseded-by-future-architecture.md +37 -0
  253. package/docs/future-architecture/adr/0008-internal-grpc-external-rest-mcp.md +106 -0
  254. package/docs/future-architecture/adr/0009-external-protocol-dialects.md +94 -0
  255. package/docs/future-architecture/adr/0010-lambda-as-inspiration-not-runtime.md +86 -0
  256. package/docs/future-architecture/adr/0011-kata-as-first-class-dind-runtime.md +84 -0
  257. package/docs/future-architecture/antipatterns.md +552 -0
  258. package/docs/future-architecture/architecture/01-layers.md +109 -0
  259. package/docs/future-architecture/architecture/02-layer4-control-plane.md +122 -0
  260. package/docs/future-architecture/architecture/03-layer3-providers.md +174 -0
  261. package/docs/future-architecture/architecture/04-layer2-runtimes.md +114 -0
  262. package/docs/future-architecture/architecture/04b-credential-broker.md +153 -0
  263. package/docs/future-architecture/architecture/05-layer1-guest-agent.md +138 -0
  264. package/docs/future-architecture/architecture/06-storage.md +134 -0
  265. package/docs/future-architecture/architecture/07-security.md +194 -0
  266. package/docs/future-architecture/architecture/08-networking.md +149 -0
  267. package/docs/future-architecture/architecture/09-templates.md +122 -0
  268. package/docs/future-architecture/architecture/10-observability.md +121 -0
  269. package/docs/future-architecture/design-notes.md +72 -0
  270. package/docs/future-architecture/gaps.md +281 -0
  271. package/docs/future-architecture/phase-template.md +123 -0
  272. package/docs/future-architecture/references.md +225 -0
  273. package/docs/future-architecture/research/01-kata-containers.md +100 -0
  274. package/docs/future-architecture/research/02-e2b-infra.md +133 -0
  275. package/docs/future-architecture/research/03-coder.md +115 -0
  276. package/docs/future-architecture/research/04-cloud-hypervisor.md +99 -0
  277. package/docs/future-architecture/research/05-firecracker.md +114 -0
  278. package/docs/future-architecture/research/06-agent-sandbox.md +142 -0
  279. package/docs/future-architecture/research/07-chromedp.md +78 -0
  280. package/docs/future-architecture/research/08-microsandbox.md +78 -0
  281. package/docs/future-architecture/research/09-agentbox.md +135 -0
  282. package/docs/future-architecture/research/10-sysbox.md +100 -0
  283. package/docs/future-architecture/research/11-firecracker-containerd.md +93 -0
  284. package/docs/future-architecture/research/12-docker-socket-proxy.md +59 -0
  285. package/docs/future-architecture/research/14-e2b-desktop-and-surf.md +107 -0
  286. package/docs/future-architecture/research/18-open-webui-terminals-observed.md +135 -0
  287. package/docs/future-architecture/research/bank-buyer.md +96 -0
  288. package/docs/future-architecture/research/enthusiast-audience.md +106 -0
  289. package/docs/future-architecture/research/proof-uipath-anthropic-2026-05.md +76 -0
  290. package/docs/future-architecture/research/widemoat-thesis-advisor.md +124 -0
  291. package/docs/future-architecture/roadmap.md +438 -0
  292. package/docs/kata-runtime.md +267 -0
  293. package/docs/kubernetes.md +86 -0
  294. package/docs/logo.png +0 -0
  295. package/docs/multi-cli.md +161 -0
  296. package/docs/openwebui-filter.md +134 -0
  297. package/docs/roadmap/implementation-roadmap.md +104 -0
  298. package/docs/sandbox-contents.svg +229 -0
  299. package/docs/screenshots/01-create-document.png +0 -0
  300. package/docs/screenshots/02-file-preview.png +0 -0
  301. package/docs/screenshots/03-browser-viewer.png +0 -0
  302. package/docs/screenshots/04-sub-agent-terminal.png +0 -0
  303. package/docs/screenshots/05-chat-overview.png +0 -0
  304. package/docs/screenshots/06-sub-agent-dashboard.png +0 -0
  305. package/docs/screenshots/07-frontend-design-skill.png +0 -0
  306. package/docs/screenshots/08-pptx-skill.png +0 -0
  307. package/docs/screenshots/09-skill-creator.png +0 -0
  308. package/docs/screenshots/10-data-chart.png +0 -0
  309. package/docs/shared-browser.svg +102 -0
  310. package/docs/system-prompt.md +113 -0
  311. package/docs/terminal-flow.svg +69 -0
  312. package/examples/helm/README.md +20 -0
  313. package/examples/helm/standalone/values.yaml +49 -0
  314. package/examples/helm/with-open-webui/README.md +99 -0
  315. package/examples/helm/with-open-webui/values-computer-use.yaml +32 -0
  316. package/examples/helm/with-open-webui/values-open-webui.yaml +67 -0
  317. package/fonts/NotoEmoji-Regular.ttf +0 -0
  318. package/helm/computer-use-server/.helmignore +17 -0
  319. package/helm/computer-use-server/Chart.yaml +32 -0
  320. package/helm/computer-use-server/README.md +211 -0
  321. package/helm/computer-use-server/templates/NOTES.txt +66 -0
  322. package/helm/computer-use-server/templates/_helpers.tpl +115 -0
  323. package/helm/computer-use-server/templates/configmap-dind-init.yaml +82 -0
  324. package/helm/computer-use-server/templates/configmap.yaml +18 -0
  325. package/helm/computer-use-server/templates/deployment.yaml +248 -0
  326. package/helm/computer-use-server/templates/ingress.yaml +38 -0
  327. package/helm/computer-use-server/templates/networkpolicy.yaml +50 -0
  328. package/helm/computer-use-server/templates/pdb.yaml +16 -0
  329. package/helm/computer-use-server/templates/pvc-data.yaml +20 -0
  330. package/helm/computer-use-server/templates/pvc-skills-cache.yaml +20 -0
  331. package/helm/computer-use-server/templates/pvc-user-data.yaml +20 -0
  332. package/helm/computer-use-server/templates/pvc-var-lib-docker.yaml +27 -0
  333. package/helm/computer-use-server/templates/secret.yaml +23 -0
  334. package/helm/computer-use-server/templates/service.yaml +22 -0
  335. package/helm/computer-use-server/templates/serviceaccount.yaml +15 -0
  336. package/helm/computer-use-server/templates/tests/test-health.yaml +23 -0
  337. package/helm/computer-use-server/values.schema.json +183 -0
  338. package/helm/computer-use-server/values.yaml +297 -0
  339. package/lychee.toml +36 -0
  340. package/openwebui/Dockerfile +52 -0
  341. package/openwebui/README.md +38 -0
  342. package/openwebui/functions/README.md +48 -0
  343. package/openwebui/functions/computer_link_filter.py +487 -0
  344. package/openwebui/init.sh +305 -0
  345. package/openwebui/patches/README.md +44 -0
  346. package/openwebui/patches/fix_artifacts_auto_show.py +441 -0
  347. package/openwebui/patches/fix_attached_files_position.py +87 -0
  348. package/openwebui/patches/fix_large_tool_args.py +156 -0
  349. package/openwebui/patches/fix_large_tool_results.py +289 -0
  350. package/openwebui/patches/fix_preview_url_detection.py +230 -0
  351. package/openwebui/patches/fix_skip_embedding_chat_files.py +229 -0
  352. package/openwebui/patches/fix_skip_rag_files_native_fc.py +100 -0
  353. package/openwebui/patches/fix_tool_loop_errors.py +510 -0
  354. package/package.json +39 -0
  355. package/requirements.txt +112 -0
  356. package/scripts/check-config.sh +141 -0
  357. package/scripts/docs-lint/ai-slop-detector.sh +202 -0
  358. package/scripts/docs-lint/architecture-tree-whitelist.sh +131 -0
  359. package/scripts/docs-lint/ascii-diagram-detector.sh +58 -0
  360. package/scripts/docs-lint/front-matter-validator.sh +97 -0
  361. package/scripts/docs-lint/gitignored-ref-detector.sh +122 -0
  362. package/scripts/docs-lint/identity-email-detector.sh +48 -0
  363. package/scripts/docs-lint/test-linters.sh +354 -0
  364. package/scripts/docs-lint/wc-budget.sh +61 -0
  365. package/scripts/githooks/pre-push +75 -0
  366. package/server.json +13 -0
  367. package/settings-wrapper/Dockerfile +9 -0
  368. package/settings-wrapper/README.md +119 -0
  369. package/settings-wrapper/app.py +113 -0
  370. package/settings-wrapper/requirements.txt +2 -0
  371. package/settings-wrapper/skills.json +25 -0
  372. package/skills/README.md +46 -0
  373. package/skills/examples/algorithmic-art/SKILL.md +405 -0
  374. package/skills/examples/algorithmic-art/templates/generator_template.js +223 -0
  375. package/skills/examples/algorithmic-art/templates/viewer.html +601 -0
  376. package/skills/examples/artifacts-builder/SKILL.md +74 -0
  377. package/skills/examples/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  378. package/skills/examples/artifacts-builder/scripts/init-artifact.sh +322 -0
  379. package/skills/examples/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  380. package/skills/examples/canvas-design/LICENSE.txt +202 -0
  381. package/skills/examples/canvas-design/SKILL.md +130 -0
  382. package/skills/examples/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  383. package/skills/examples/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  384. package/skills/examples/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  385. package/skills/examples/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  386. package/skills/examples/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  387. package/skills/examples/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  388. package/skills/examples/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  389. package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  390. package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  391. package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  392. package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  393. package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  394. package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  395. package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  396. package/skills/examples/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  397. package/skills/examples/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  398. package/skills/examples/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  399. package/skills/examples/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  400. package/skills/examples/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  401. package/skills/examples/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  402. package/skills/examples/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  403. package/skills/examples/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  404. package/skills/examples/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  405. package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  406. package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  407. package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  408. package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  409. package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  410. package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  411. package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  412. package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  413. package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  414. package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  415. package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  416. package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  417. package/skills/examples/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  418. package/skills/examples/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  419. package/skills/examples/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  420. package/skills/examples/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  421. package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  422. package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  423. package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  424. package/skills/examples/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  425. package/skills/examples/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  426. package/skills/examples/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  427. package/skills/examples/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  428. package/skills/examples/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  429. package/skills/examples/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  430. package/skills/examples/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  431. package/skills/examples/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  432. package/skills/examples/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  433. package/skills/examples/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  434. package/skills/examples/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  435. package/skills/examples/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  436. package/skills/examples/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  437. package/skills/examples/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  438. package/skills/examples/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  439. package/skills/examples/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  440. package/skills/examples/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  441. package/skills/examples/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  442. package/skills/examples/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  443. package/skills/examples/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  444. package/skills/examples/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  445. package/skills/examples/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  446. package/skills/examples/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  447. package/skills/examples/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  448. package/skills/examples/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  449. package/skills/examples/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  450. package/skills/examples/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  451. package/skills/examples/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  452. package/skills/examples/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  453. package/skills/examples/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  454. package/skills/examples/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  455. package/skills/examples/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  456. package/skills/examples/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  457. package/skills/examples/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  458. package/skills/examples/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  459. package/skills/examples/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  460. package/skills/examples/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  461. package/skills/examples/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  462. package/skills/examples/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  463. package/skills/examples/copy-editing/SKILL.md +447 -0
  464. package/skills/examples/copy-editing/evals/evals.json +89 -0
  465. package/skills/examples/copy-editing/references/plain-english-alternatives.md +394 -0
  466. package/skills/examples/internal-comms/LICENSE.txt +202 -0
  467. package/skills/examples/internal-comms/SKILL.md +32 -0
  468. package/skills/examples/internal-comms/examples/3p-updates.md +47 -0
  469. package/skills/examples/internal-comms/examples/company-newsletter.md +65 -0
  470. package/skills/examples/internal-comms/examples/faq-answers.md +30 -0
  471. package/skills/examples/internal-comms/examples/general-comms.md +16 -0
  472. package/skills/examples/mcp-builder/SKILL.md +328 -0
  473. package/skills/examples/mcp-builder/reference/evaluation.md +602 -0
  474. package/skills/examples/mcp-builder/reference/mcp_best_practices.md +915 -0
  475. package/skills/examples/mcp-builder/reference/node_mcp_server.md +916 -0
  476. package/skills/examples/mcp-builder/reference/python_mcp_server.md +752 -0
  477. package/skills/examples/mcp-builder/scripts/connections.py +151 -0
  478. package/skills/examples/mcp-builder/scripts/evaluation.py +373 -0
  479. package/skills/examples/mcp-builder/scripts/example_evaluation.xml +22 -0
  480. package/skills/examples/mcp-builder/scripts/requirements.txt +2 -0
  481. package/skills/examples/product-marketing-context/SKILL.md +241 -0
  482. package/skills/examples/product-marketing-context/evals/evals.json +85 -0
  483. package/skills/examples/single-cell-rna-qc/SKILL.md +175 -0
  484. package/skills/examples/single-cell-rna-qc/references/scverse_qc_guidelines.md +186 -0
  485. package/skills/examples/single-cell-rna-qc/scripts/qc_analysis.py +232 -0
  486. package/skills/examples/single-cell-rna-qc/scripts/qc_core.py +233 -0
  487. package/skills/examples/single-cell-rna-qc/scripts/qc_plotting.py +235 -0
  488. package/skills/examples/skill-creator/SKILL.md +355 -0
  489. package/skills/examples/skill-creator/references/output-patterns.md +82 -0
  490. package/skills/examples/skill-creator/references/workflows.md +28 -0
  491. package/skills/examples/skill-creator/scripts/init_skill.py +303 -0
  492. package/skills/examples/skill-creator/scripts/package_skill.py +110 -0
  493. package/skills/examples/skill-creator/scripts/quick_validate.py +95 -0
  494. package/skills/examples/slack-gif-creator/SKILL.md +254 -0
  495. package/skills/examples/slack-gif-creator/core/easing.py +234 -0
  496. package/skills/examples/slack-gif-creator/core/frame_composer.py +176 -0
  497. package/skills/examples/slack-gif-creator/core/gif_builder.py +269 -0
  498. package/skills/examples/slack-gif-creator/core/validators.py +136 -0
  499. package/skills/examples/slack-gif-creator/requirements.txt +4 -0
  500. package/skills/examples/social-content/SKILL.md +278 -0
  501. package/skills/examples/social-content/evals/evals.json +92 -0
  502. package/skills/examples/social-content/references/platforms.md +170 -0
  503. package/skills/examples/social-content/references/post-templates.md +177 -0
  504. package/skills/examples/social-content/references/reverse-engineering.md +195 -0
  505. package/skills/examples/theme-factory/SKILL.md +59 -0
  506. package/skills/examples/theme-factory/theme-showcase.pdf +0 -0
  507. package/skills/examples/theme-factory/themes/arctic-frost.md +19 -0
  508. package/skills/examples/theme-factory/themes/botanical-garden.md +19 -0
  509. package/skills/examples/theme-factory/themes/desert-rose.md +19 -0
  510. package/skills/examples/theme-factory/themes/forest-canopy.md +19 -0
  511. package/skills/examples/theme-factory/themes/golden-hour.md +19 -0
  512. package/skills/examples/theme-factory/themes/midnight-galaxy.md +19 -0
  513. package/skills/examples/theme-factory/themes/modern-minimalist.md +19 -0
  514. package/skills/examples/theme-factory/themes/ocean-depths.md +19 -0
  515. package/skills/examples/theme-factory/themes/sunset-boulevard.md +19 -0
  516. package/skills/examples/theme-factory/themes/tech-innovation.md +19 -0
  517. package/skills/examples/web-artifacts-builder/LICENSE.txt +202 -0
  518. package/skills/examples/web-artifacts-builder/SKILL.md +74 -0
  519. package/skills/examples/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  520. package/skills/examples/web-artifacts-builder/scripts/init-artifact.sh +322 -0
  521. package/skills/examples/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  522. package/skills/examples/writing-skills/SKILL.md +655 -0
  523. package/skills/examples/writing-skills/anthropic-best-practices.md +1150 -0
  524. package/skills/examples/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  525. package/skills/examples/writing-skills/graphviz-conventions.dot +172 -0
  526. package/skills/examples/writing-skills/persuasion-principles.md +187 -0
  527. package/skills/examples/writing-skills/render-graphs.js +168 -0
  528. package/skills/examples/writing-skills/testing-skills-with-subagents.md +384 -0
  529. package/skills/public/describe-image/SKILL.md +105 -0
  530. package/skills/public/describe-image/scripts/describe.py +389 -0
  531. package/skills/public/doc-coauthoring/SKILL.md +375 -0
  532. package/skills/public/docx/LICENSE.txt +30 -0
  533. package/skills/public/docx/SKILL.md +199 -0
  534. package/skills/public/docx/docx-js.md +350 -0
  535. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  536. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  537. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  538. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  539. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  540. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  541. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  542. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  543. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  544. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  545. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  546. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  547. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  548. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  549. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  550. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  551. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  552. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  553. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  554. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  555. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  556. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  557. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  558. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  559. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  560. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  561. package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  562. package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  563. package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  564. package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  565. package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  566. package/skills/public/docx/ooxml/schemas/mce/mc.xsd +75 -0
  567. package/skills/public/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  568. package/skills/public/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  569. package/skills/public/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  570. package/skills/public/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  571. package/skills/public/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  572. package/skills/public/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  573. package/skills/public/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  574. package/skills/public/docx/ooxml/scripts/pack.py +159 -0
  575. package/skills/public/docx/ooxml/scripts/unpack.py +29 -0
  576. package/skills/public/docx/ooxml/scripts/validate.py +69 -0
  577. package/skills/public/docx/ooxml/scripts/validation/__init__.py +15 -0
  578. package/skills/public/docx/ooxml/scripts/validation/base.py +951 -0
  579. package/skills/public/docx/ooxml/scripts/validation/docx.py +274 -0
  580. package/skills/public/docx/ooxml/scripts/validation/pptx.py +315 -0
  581. package/skills/public/docx/ooxml/scripts/validation/redlining.py +279 -0
  582. package/skills/public/docx/ooxml.md +632 -0
  583. package/skills/public/docx/scripts/__init__.py +1 -0
  584. package/skills/public/docx/scripts/document.py +1292 -0
  585. package/skills/public/docx/scripts/templates/comments.xml +3 -0
  586. package/skills/public/docx/scripts/templates/commentsExtended.xml +3 -0
  587. package/skills/public/docx/scripts/templates/commentsExtensible.xml +3 -0
  588. package/skills/public/docx/scripts/templates/commentsIds.xml +3 -0
  589. package/skills/public/docx/scripts/templates/people.xml +3 -0
  590. package/skills/public/docx/scripts/utilities.py +374 -0
  591. package/skills/public/file-reading/LICENSE.txt +30 -0
  592. package/skills/public/file-reading/SKILL.md +350 -0
  593. package/skills/public/frontend-design/LICENSE.txt +177 -0
  594. package/skills/public/frontend-design/SKILL.md +42 -0
  595. package/skills/public/gitlab-explorer/SKILL.md +174 -0
  596. package/skills/public/gitlab-explorer/references/git-commands.md +323 -0
  597. package/skills/public/gitlab-explorer/references/glab-commands.md +282 -0
  598. package/skills/public/gitlab-explorer/scripts/check_gitlab_auth.sh +109 -0
  599. package/skills/public/pdf/FORMS.md +205 -0
  600. package/skills/public/pdf/REFERENCE.md +612 -0
  601. package/skills/public/pdf/SKILL.md +364 -0
  602. package/skills/public/pdf/scripts/check_bounding_boxes.py +70 -0
  603. package/skills/public/pdf/scripts/check_bounding_boxes_test.py +226 -0
  604. package/skills/public/pdf/scripts/check_fillable_fields.py +12 -0
  605. package/skills/public/pdf/scripts/convert_pdf_to_images.py +35 -0
  606. package/skills/public/pdf/scripts/create_validation_image.py +41 -0
  607. package/skills/public/pdf/scripts/extract_form_field_info.py +152 -0
  608. package/skills/public/pdf/scripts/fill_fillable_fields.py +114 -0
  609. package/skills/public/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  610. package/skills/public/pdf-reading/LICENSE.txt +30 -0
  611. package/skills/public/pdf-reading/REFERENCE.md +196 -0
  612. package/skills/public/pdf-reading/SKILL.md +305 -0
  613. package/skills/public/playwright-cli/SKILL.md +278 -0
  614. package/skills/public/playwright-cli/references/request-mocking.md +87 -0
  615. package/skills/public/playwright-cli/references/running-code.md +232 -0
  616. package/skills/public/playwright-cli/references/session-management.md +169 -0
  617. package/skills/public/playwright-cli/references/storage-state.md +275 -0
  618. package/skills/public/playwright-cli/references/test-generation.md +88 -0
  619. package/skills/public/playwright-cli/references/tracing.md +139 -0
  620. package/skills/public/playwright-cli/references/video-recording.md +43 -0
  621. package/skills/public/pptx/LICENSE.txt +30 -0
  622. package/skills/public/pptx/SKILL.md +484 -0
  623. package/skills/public/pptx/css.md +335 -0
  624. package/skills/public/pptx/html2pptx.md +893 -0
  625. package/skills/public/pptx/html2pptx.tgz +0 -0
  626. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  627. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  628. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  629. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  630. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  631. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  632. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  633. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  634. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  635. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  636. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  637. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  638. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  639. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  640. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  641. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  642. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  643. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  644. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  645. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  646. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  647. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  648. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  649. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  650. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  651. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  652. package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  653. package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  654. package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  655. package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  656. package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  657. package/skills/public/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  658. package/skills/public/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  659. package/skills/public/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  660. package/skills/public/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  661. package/skills/public/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  662. package/skills/public/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  663. package/skills/public/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  664. package/skills/public/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  665. package/skills/public/pptx/ooxml/scripts/pack.py +159 -0
  666. package/skills/public/pptx/ooxml/scripts/unpack.py +29 -0
  667. package/skills/public/pptx/ooxml/scripts/validate.py +69 -0
  668. package/skills/public/pptx/ooxml/scripts/validation/__init__.py +15 -0
  669. package/skills/public/pptx/ooxml/scripts/validation/base.py +951 -0
  670. package/skills/public/pptx/ooxml/scripts/validation/docx.py +274 -0
  671. package/skills/public/pptx/ooxml/scripts/validation/pptx.py +315 -0
  672. package/skills/public/pptx/ooxml/scripts/validation/redlining.py +279 -0
  673. package/skills/public/pptx/ooxml.md +427 -0
  674. package/skills/public/pptx/scripts/inventory.py +1020 -0
  675. package/skills/public/pptx/scripts/rearrange.py +231 -0
  676. package/skills/public/pptx/scripts/replace.py +385 -0
  677. package/skills/public/pptx/scripts/thumbnail.py +450 -0
  678. package/skills/public/skill-creator/SKILL.md +356 -0
  679. package/skills/public/skill-creator/references/output-patterns.md +82 -0
  680. package/skills/public/skill-creator/references/workflows.md +28 -0
  681. package/skills/public/skill-creator/scripts/init_skill.py +303 -0
  682. package/skills/public/skill-creator/scripts/package_skill.py +110 -0
  683. package/skills/public/skill-creator/scripts/quick_validate.py +95 -0
  684. package/skills/public/sub-agent/SKILL.md +186 -0
  685. package/skills/public/sub-agent/references/security-review.md +153 -0
  686. package/skills/public/sub-agent/references/usage.md +207 -0
  687. package/skills/public/sub-agent/scripts/list_subagent_models.sh +22 -0
  688. package/skills/public/test-driven-development/SKILL.md +371 -0
  689. package/skills/public/test-driven-development/testing-anti-patterns.md +299 -0
  690. package/skills/public/webapp-testing/LICENSE.txt +202 -0
  691. package/skills/public/webapp-testing/SKILL.md +96 -0
  692. package/skills/public/webapp-testing/examples/console_logging.py +35 -0
  693. package/skills/public/webapp-testing/examples/element_discovery.py +40 -0
  694. package/skills/public/webapp-testing/examples/static_html_automation.py +33 -0
  695. package/skills/public/webapp-testing/scripts/with_server.py +106 -0
  696. package/skills/public/xlsx/LICENSE.txt +30 -0
  697. package/skills/public/xlsx/SKILL.md +316 -0
  698. package/skills/public/xlsx/preview_data.py +93 -0
  699. package/skills/public/xlsx/recalc.py +178 -0
  700. package/tests/README.md +42 -0
  701. package/tests/fixtures/cli/claude_v0.9.2.0_argv.json +46 -0
  702. package/tests/fixtures/cli/claude_v0.9.2.0_stdout.json +32 -0
  703. package/tests/fixtures/cli/codex_run.jsonl +4 -0
  704. package/tests/fixtures/cli/opencode_run.jsonl +6 -0
  705. package/tests/integration/README.md +56 -0
  706. package/tests/integration/conftest.py +280 -0
  707. package/tests/integration/pytest.ini +13 -0
  708. package/tests/integration/test_mcp_auth.py +85 -0
  709. package/tests/integration/test_mcp_tools.py +101 -0
  710. package/tests/integration/test_workspace_lifecycle.py +125 -0
  711. package/tests/orchestrator/mock_llm_server.py +343 -0
  712. package/tests/orchestrator/test_cli_adapters.py +566 -0
  713. package/tests/orchestrator/test_cli_adapters_live.py +527 -0
  714. package/tests/orchestrator/test_cli_runtime.py +451 -0
  715. package/tests/orchestrator/test_docker_manager.py +302 -0
  716. package/tests/orchestrator/test_dynamic_instructions.py +69 -0
  717. package/tests/orchestrator/test_mcp_resources.py +140 -0
  718. package/tests/orchestrator/test_mcp_tools.py +224 -0
  719. package/tests/orchestrator/test_passthrough_isolation.py +201 -0
  720. package/tests/orchestrator/test_readme_in_container.py +76 -0
  721. package/tests/orchestrator/test_render_cache.py +84 -0
  722. package/tests/orchestrator/test_runtime_cli_endpoint.py +108 -0
  723. package/tests/orchestrator/test_single_user_mode.py +212 -0
  724. package/tests/orchestrator/test_startup_warnings.py +123 -0
  725. package/tests/orchestrator/test_sub_agent_dispatch.py +327 -0
  726. package/tests/orchestrator/test_subagent_claude_compat.py +367 -0
  727. package/tests/orchestrator/test_system_prompt_endpoint.py +191 -0
  728. package/tests/orchestrator/test_tool_descriptions.py +52 -0
  729. package/tests/orchestrator/test_view_image.py +201 -0
  730. package/tests/patches/conftest.py +30 -0
  731. package/tests/patches/fixtures/__init__.py +10 -0
  732. package/tests/patches/fixtures/middleware_v0.9.1.py +5057 -0
  733. package/tests/patches/fixtures/middleware_v0.9.2.py +5120 -0
  734. package/tests/patches/fixtures/retrieval_v0.9.1.py +2684 -0
  735. package/tests/patches/fixtures/retrieval_v0.9.2.py +2700 -0
  736. package/tests/patches/test_fix_attached_files_position.py +118 -0
  737. package/tests/patches/test_fix_large_tool_args.py +130 -0
  738. package/tests/patches/test_fix_large_tool_results.py +531 -0
  739. package/tests/patches/test_fix_skip_embedding_chat_files.py +160 -0
  740. package/tests/patches/test_fix_skip_rag_files_native_fc.py +120 -0
  741. package/tests/patches/test_fix_tool_loop_errors.py +128 -0
  742. package/tests/security/test_path_traversal_app.py +132 -0
  743. package/tests/security/test_path_traversal_docker.py +36 -0
  744. package/tests/security/test_path_traversal_settings.py +87 -0
  745. package/tests/security/test_safe_path_util.py +166 -0
  746. package/tests/security/test_xss_preview.py +46 -0
  747. package/tests/test-default-model-resolution.py +136 -0
  748. package/tests/test-docker-image.sh +358 -0
  749. package/tests/test-list-subagent-models.sh +421 -0
  750. package/tests/test-mcp-endpoint-live.sh +92 -0
  751. package/tests/test-mcp-native-surface.sh +213 -0
  752. package/tests/test-no-cyrillic.sh +135 -0
  753. package/tests/test-opencode-error-mapping.py +130 -0
  754. package/tests/test-pr88-skills.sh +305 -0
  755. package/tests/test-project-structure.sh +202 -0
  756. package/tests/test-single-user-mode.sh +269 -0
  757. package/tests/test-skill-no-hardcoded-models.sh +65 -0
  758. package/tests/test-subagent-cli-surface.py +137 -0
  759. package/tests/test-subagent-runtime.sh +109 -0
  760. package/tests/test_codex_toml_converter.py +204 -0
  761. package/tests/test_default_resolver_no_legacy_global.py +159 -0
  762. package/tests/test_filter.py +648 -0
  763. package/tests/test_init_sh_unchanged.sh +49 -0
  764. package/tests/test_opencode_alias_map_drop.py +144 -0
  765. package/tests/test_requirements.py +91 -0
  766. package/tests/test_subagent_docstring.py +193 -0
  767. package/tests/test_tools.py +34 -0
  768. package/vendor/extract-text/README.md +46 -0
  769. package/vendor/extract-text/extract-text +0 -0
@@ -0,0 +1,57 @@
1
+ <!-- SPDX-License-Identifier: FSL-1.1-Apache-2.0 -->
2
+ <!-- Copyright (c) 2025 Open Computer Use Contributors -->
3
+
4
+ ---
5
+ status: draft
6
+ last-reviewed: 2026-05-30
7
+ owner: "@Wide-Moat/architects"
8
+ applies-to: next/v1
9
+ ---
10
+
11
+ Names who Wide-Moat is built for, who can stop a deployment from happening, and why those people are buying in 2026 rather than 2024 or 2028. Audience is anyone proposing a change that affects buyer-facing surface area.
12
+
13
+ ## Audience
14
+
15
+ Wide-Moat is built for any organisation that needs in-perimeter agentic AI. The capability ceiling targets the requirements of a tier-1 US or EU bank — the most demanding regulatory and operational-scale envelope we design against — so smaller and less-regulated organisations fit beneath it on the same artifact. Primary commercial focus and trust anchor are tier-1 banks; the product is one product, not a tiered SKU. The 2026 use-cases that close at this tier are KYC/AML investigator assistance, internal IT-helpdesk automation, sandboxed developer productivity, and compliance-evidence collection.
16
+
17
+ Wide-Moat is sold as an in-perimeter ecosystem subscription — a single integrated platform with enablement and certification, not as separable components.
18
+
19
+ The platform serves two human personas inside the customer organisation:
20
+
21
+ 1. **Business users** consume agents through chat surfaces, workflows, and dashboards. They never see the platform plumbing.
22
+ 2. **Builder and platform engineers** inside the customer create skills, MCP servers, n8n workflows, observability dashboards, and eval suites. They are the customer's internal multipliers; the training and enablement Wide-Moat sells is for them.
23
+
24
+ Agents are treated as a first-class architectural concern below the human personas — they call tools, execute browser sessions, and emit audit events through OCU's stable contracts (MCP, the sandbox runtime API, the replay bundle schema). They are a design constraint, not a buyer.
25
+
26
+ A solo enthusiast audience exists as a downstream consequence of the FSL-1.1-Apache-2.0 licence (full posture lands in §05 — see issue `arch/manifesto-05-licensing-posture`), not as a co-equal persona. Anyone may self-host, fork, and modify the platform. Expected contribution channels are evaluation submissions, hardening reports, MCP server and skill contributions, and public engineering writeups. Security primitives ship in the open artifact; the commercial moat is operational, not capability.
27
+
28
+ ## Buyer chain
29
+
30
+ A purchase requires alignment across four parallel chains; each chain holds at least one veto, and the gatekeeper chain contains four independent vetoes.
31
+
32
+ 1. **Business sponsor and budget** — Chief AI Officer where the title exists (HSBC, UBS, CBA, NatWest as of 2026); the function is assumed to exist at every tier-1 by end-2026 even where the title does not (uncited assumption — see Open Question 1).
33
+ 2. **Technical owner** — CIO or Head of Engineering Platforms; owns the runtime, the SLOs, and the bill.
34
+ 3. **Gatekeeper stack** — CISO, Chief Risk Officer, Chief Compliance Officer, Data Protection Officer; any one of them can stop the deal in InfoSec or third-party-risk review.
35
+ 4. **Procurement and Legal** — runs the third-party-risk-management intake and the licence redline.
36
+
37
+ The top deal-killer in 2026 is the third-party-risk-management (TPRM) function, driven by three independent regulator actions. NYDFS Industry Letter of 21 October 2025 binds covered entities to AI-specific contractual requirements on third-party AI use, training-data limits, sub-processor disclosure, and exit obligations. DORA Articles 28–30 (EU) mandate a Register of Information with seven required fields per ICT provider plus explicit concentration-risk management. Supervisory Letter SR 26-2 (17 April 2026) excludes generative and agentic AI from Model Risk Management scope.
38
+
39
+ The consequence: the veto moves from model-risk reviewers to TPRM, operational-risk, and cyber reviewers. The platform must satisfy that group, not the first.
40
+
41
+ ## Why now
42
+
43
+ Four forcing functions converge in 2026. DORA enforcement has been active in the EU since 17 January 2025, with 2026 the first full year of supervisory action and fines up to 2% of global turnover. NYDFS Letter of 21 October 2025 binds covered entities to AI-specific TPRM clauses. The EU AI Act Annex III high-risk obligations are deferred to 2 December 2027 (standalone) and 2 August 2028 (product-embedded) under the Digital Omnibus agreement of 7 May 2026 — the procurement window is open and narrow, not closed. IBM Cost of a Data Breach 2025 puts shadow-AI breach cost at $4.63M average ($670K premium over baseline); 97% of AI-breach victims lacked basic AI access controls. BCG's 2025 retail-banking report puts at-scale AI adoption at ~10%, with 75% of banks still experimenting.
44
+
45
+ ## Positioning thesis
46
+
47
+ Wide-Moat assembles an in-perimeter agentic AI ecosystem and sells it as a deployable subscription with enablement and certification. Every component runs entirely inside the customer's perimeter (including the agent loop, the context store, and the recovery logic — not only the tool-execution sandbox). The platform is model-agnostic by construction (MCP-first, no hosted loop); SOC 2 Type II, ISO 27001, DORA Article 28–30, and EU AI Act Annex III evidence ships as first-class build artifacts on every release. The licence is FSL-1.1-Apache-2.0 with a planned `LICENSE-ADDITIONAL-PERMISSIONS.md` instrument (tracked in issue `arch/additional-permissions-instrument`; drafted in the research buffer; lands at repo root and in §05 once that section is written) enumerating internal-use scope for affiliates, joint ventures, outsourced operators, single-tenant managed deployments, and internal white-labelling; reselling as a competing multi-tenant SaaS remains forbidden during the FSL term (including by Wide-Moat itself), with each release converting to Apache 2.0 two years after publication per the License's Future License Grant.
48
+
49
+ In-perimeter deployment alone is no longer a moat. UiPath Automation Suite shipped on-prem agentic AI on 5 May 2026 under a commercial closed-source EULA; Anthropic shipped self-hosted sandboxes on 19 May 2026 with the agent loop, context, and model weights kept on Anthropic infrastructure. The remaining moat is the intersection of model-neutrality, source availability, fully in-perimeter execution (loop included), and per-release compliance evidence. These are bundle properties: the loop and model-neutrality come from sibling components (Open WebUI / n8n / LiteLLM); Open Computer Use — the component these architecture docs design — contributes the in-perimeter tool-execution sandbox and the tamper-evident audit lineage, and does not run the loop or proxy a model. Re-evaluates on 2027-05-24.
50
+
51
+ ## Open questions
52
+
53
+ 1. Is "CAIO is the modal sponsor" true at JPMorgan, Goldman Sachs, and Morgan Stanley, where AI strategy currently runs through existing CTO/COO structures? Track in issue `arch/caio-modal-sponsor-validation`.
54
+ 2. What is the actual procurement experience of FSL-1.1-Apache-2.0 plus the Additional Permissions instrument in three or more tier-1 customers? Track in issue `arch/fsl-procurement-evidence`.
55
+ 3. Does "first-class build artifact" for compliance evidence mean a signed bundle per release, a continuously-updated portal, or both? Track in issue `arch/thesis-evidence-bundle`.
56
+ 4. Does "model-agnostic by construction" extend to embedding and rerank models, or only generation models? Track in issue `arch/modelprovider-scope`.
57
+ 5. Public-sector and academic-consortium deployments need a §8 in the Additional Permissions instrument or bilateral side letters; which? Track in issue `arch/additional-permissions-edge-cases`.
@@ -0,0 +1,325 @@
1
+ <!-- SPDX-License-Identifier: FSL-1.1-Apache-2.0 -->
2
+ <!-- Copyright (c) 2025 Open Computer Use Contributors -->
3
+
4
+ ---
5
+ status: draft
6
+ last-reviewed: 2026-06-06
7
+ owner: "@Wide-Moat/architects"
8
+ applies-to: next/v1
9
+ ---
10
+
11
+ Names the measurable non-functional requirements every Wide-Moat release must satisfy. Audience is anyone proposing a component spec, ADR, or CI gate that affects buyer-facing surface area.
12
+
13
+ Categories follow ISO/IEC 25010:2023 plus two inserted sections (Compliance, Cost) that have no native ISO mapping.
14
+
15
+ ## Trust boundaries
16
+
17
+ Five zones interact: Control plane, Storage broker, Compute plane, Egress trust-edge, Audit pipeline. The trust-zone diagram is canonical in [`../02-trust-boundaries.md`](../02-trust-boundaries.md) §5 (source: [`../diagrams/02-trust-boundaries.mmd`](../diagrams/02-trust-boundaries.mmd)). Every NFR below sits on one of those zones.
18
+
19
+ Two identity primitives carry the inter-zone calls: a session JWT bound to `container_name` (Control plane → Compute plane, TTL ≤ 60 min, rotated), and a network-bound egress route (Compute plane → Egress trust-edge: the sandbox's sole outbound path). The guest holds no long-lived upstream secret (it may hold a short-lived session-scoped handle, which is not the upstream key). Upstream authorization is attached at the Egress trust-edge, which receives the credential over Envoy SDS from a static file (solo) or a customer-provided SDS-compatible store (enterprise) and injects it on the re-originated leg, keyed on a presented scoped credential and never on network origin (ADR-0007); the sandbox never sees the key. Component skeletons land under [`../components/`](../components/) when each component spec opens (see [PROCESS.md](../PROCESS.md)).
20
+
21
+ ### Token TTL taxonomy
22
+
23
+ Four token classes carry different lifetimes by design. The guest holds only session-scoped tokens — the session JWT and a storage-mount handle; the two host-side classes never enter the sandbox.
24
+
25
+ | Class | Scope | TTL | Holder | Where |
26
+ |---|---|---|---|---|
27
+ | Session JWT | per session (user sees one continuous interaction) | ≤60 min, rotated | guest (proves session identity to Control plane) | NFR-SEC-10 |
28
+ | Storage-mount handle | per session, scoped to one filesystem (a `filesystem_id`) | session-scoped (expires with the session) | guest (presented to the Storage broker; carries no backend credential) | NFR-SEC-25 |
29
+ | Generic internal token | inter-component RPC, host-side | ≤60 min | host-side services | NFR-SEC-23 |
30
+
31
+ These are token lifetimes (anti-replay windows), not session controls. Session inactivity and absolute re-authentication are separate, regulator-anchored limits — idle ≤15 min (NFR-SEC-40), absolute ≤12 h (NFR-SEC-41) — and the token rotates under both. The upstream credential the Egress trust-edge attaches is not an OCU-issued token class: it is delivered over Envoy SDS and its validity window is the SDS source's; the guest holds no upstream credential.
32
+
33
+ ## Scope ownership
34
+
35
+ Every NFR row sits in one of three ownership classes. Layer 3 (`docs/architecture/02-trust-boundaries.md`) draws the boundary; this section names what we deliver vs. what we make possible.
36
+
37
+ - **DELIVER** — we ship the code, we are accountable for the measurable target. Failure = our defect. Example: sandbox escape (NFR-SEC-02), egress proxy with upstream-auth injection (NFR-SEC-05/23/29) configured over off-the-shelf Envoy SDS, audit pipeline (NFR-SEC-03 reframed for tx-log submission), RTO/RPO of our planes (NFR-REL-01/02/03), encryption defaults (NFR-SEC-33).
38
+ - **ENABLE** — we publish the contract, the telemetry, or the integration point; the customer is the principal and owns the policy/content. Failure of the surrounding posture = customer's gap, not ours. Example: DORA major-incident timeline (NFR-COMP-04 — we emit telemetry, customer classifies); NYDFS § 500.17 notification (NFR-COMP-05); IdP posture (NFR-FLEX-03 — we are the relying party).
39
+ - **REVISIT** — flagged for re-scoping in the next §02 revision. Either claims more than our scope or names a responsibility that belongs to the customer's AI gateway / data-controller / regulator-facing process. Current list (to be re-cut, not re-justified):
40
+ - NFR-FS-03 — "LLM-request byte-identical round-trip for cached request shapes": we do not proxy LLM requests, we route them through the Egress trust-edge; no request cache lives in our platform.
41
+ - NFR-REL-04 — "LLM upstream failover ≤5 min unhealthy → secondary": failover between LLM endpoints is the customer's AI gateway, not ours.
42
+ - NFR-SEC-21 — "EU AI Act Art. 15(5) candidate test suite … data poisoning, model poisoning, adversarial examples, confidentiality attacks": these are model-level threats. We are not the model.
43
+ - NFR-COMP-09 — "Post-market monitoring data flow (EU AI Act Art. 72)": Art. 72 is the deployer's monitoring obligation. We ENABLE (telemetry hooks), we don't OWN.
44
+ - NFR-COMP-10 — "DPIA / FRIA refresh": data controller does the DPIA. We supply sub-processor + data-flow inputs, we don't refresh the assessment.
45
+ - NFR-COMP-14 — "EU AI Act Art. 15 accuracy declaration": accuracy of the AI system. The customer's model, not ours.
46
+ - NFR-COMP-18 — "ISO/IEC 42001:2023 AI Management System conformance": 42001 binds the organisation deploying the AI system. We ENABLE the customer's 42001 evidence; we are not conformance-ed.
47
+ - NFR-COMP-25 — "ZDR contractual-clause checklist per supported managed LLM upstream": the customer contracts ZDR with the upstream, in the calling client that runs the loop — not in OCU. OCU neither selects the upstream nor represents its ZDR posture.
48
+ - NFR-COMP-26 — "Configurable prompt-redaction filter": AI-guardrail policy belongs to the customer's AI gateway (commercial AI-gateway product or in-perimeter model with its own guardrails). We route + audit, we don't redact prompts.
49
+
50
+ REVISIT rows stay in this catalogue at their existing IDs until the next §02 rev; Layer 3 already takes the corrected position. **Enforcement status:** REVISIT rows are **informational / non-gating** in this draft. CI gates, release acceptance, compliance attestations, and verifier passes MUST NOT enforce a REVISIT row's Target column until the row is re-cut. The row's Scenario cell carries an inline `**[REVISIT — non-gating]**` marker so the gate-author cannot miss it.
51
+
52
+ ## Sandbox tier — workload-driven selection
53
+
54
+ The sandbox runtime ladder is chosen by the trust profile of the workload running inside the sandbox, not by data classification or compliance tier.
55
+
56
+ | Workload profile (`workload_trust_profile`) | Recommended tier | Rationale |
57
+ |---|---|---|
58
+ | `trusted_operator` — solo developer, single operator; you are the only one driving the agent | `runc` (default; one-click solo install preserved) | Shared kernel; trade isolation for speed. Acceptable when you are the workload. |
59
+ | `internal_workforce` — vetted employees and partners driving the agent; you know who they are, you trust their intent | `gVisor` (`runsc`) — v1 hardened default | User-space-kernel isolation; two-bug escape requirement per gVisor's published threat model. |
60
+ | `untrusted` — unknown actors (external customers, public endpoints, untrusted skill execution) | **microVM (hardware-virt)** — post-v1, tracked at [`arch/microvm-tier-v1.1`](https://github.com/Wide-Moat/open-computer-use/issues/161) | Hardware-virtualisation is the defensible isolation primitive against unknown-actor adversarial code. Named example: Firecracker. Kata Containers is one packaging option, not a requirement. |
61
+
62
+ The `untrusted` profile is not deployable in v1 GA; admission rejects it because the microVM tier has not shipped. KVM presence is a microVM precondition. Per-session trust profiles are tracked for v1.1+ at [`arch/per-session-trust-profile`](https://github.com/Wide-Moat/open-computer-use/issues/162); v1 GA carries a single deployment-wide profile.
63
+
64
+ ## 1. Functional Suitability
65
+
66
+ Scope: determinism, replay, and reproducibility properties of the agent loop. Functional behaviour of individual components lives in the respective component specs.
67
+
68
+ | ID | Scenario | Target | Verification | Source |
69
+ |---|---|---|---|---|
70
+ | NFR-FS-01 | Per-template agent wall-clock policy — real / frozen / replayable; CRNG reseed on snapstart restore | declared per template | template field + replay test | [`gaps.md`](../../future-architecture/gaps.md) D.2 |
71
+ | NFR-FS-02 | Skill randomness honours session-fixed seed when `determinism.fixed_seed: true` | `tbd` (`arch/deterministic-skill-seed`) | per-template test | [`gaps.md`](../../future-architecture/gaps.md) D.3 |
72
+ | NFR-FS-03 | **[REVISIT — non-gating]** LLM-request byte-identical round-trip for cached request shapes (proxy semantics, not provider semantics) | CI integration test asserts | release pipeline | [`02-layer4-control-plane.md`](../../future-architecture/architecture/02-layer4-control-plane.md) §LLM proxy |
73
+
74
+ ## 2. Performance Efficiency
75
+
76
+ | ID | Scenario | Target | Verification | Source |
77
+ |---|---|---|---|---|
78
+ | NFR-PERF-01 | MCP request success rate | ≥99.9% | Prometheus blackbox | [`10-observability.md`](../../future-architecture/architecture/10-observability.md) §SLO |
79
+ | NFR-PERF-02 | Session-create p99, warm-pool hit | ≤500 ms | k6 perf gate | [`10-observability.md`](../../future-architecture/architecture/10-observability.md) §SLO |
80
+ | NFR-PERF-03 | Session-create p99, cold-start on the hardened tier (gVisor v1; microVM post-v1) | ≤2 s | k6 perf gate | per-tier baselines in NFR-PERF-07/08/09 |
81
+ | NFR-PERF-04 | Exec orchestration overhead p99 | ≤50 ms | k6 perf gate | [`10-observability.md`](../../future-architecture/architecture/10-observability.md) §SLO |
82
+ | NFR-PERF-05 | CDP frame rate | ≥10 fps | Playwright golden-path | [`10-observability.md`](../../future-architecture/architecture/10-observability.md) §SLO |
83
+ | NFR-PERF-06 | Egress-proxy latency p99 | ≤100 ms | k6 perf gate | [`10-observability.md`](../../future-architecture/architecture/10-observability.md) §SLO |
84
+ | NFR-PERF-07 | Cold-start container-substrate p99 (dev / PoC only — not GA acceptance path) | ≤200 ms | k6 perf gate | dev-tier baseline |
85
+ | NFR-PERF-08 | Cold-start user-space-kernel substrate p99 | ≤400 ms | k6 perf gate | published user-space-kernel benchmarks |
86
+ | NFR-PERF-09 | Cold-start microVM substrate p99 | ≤1500 ms baseline; pilot data may tighten to ≤800 ms. Gated on microVM tier shipping ([`arch/microvm-tier-v1.1`](https://github.com/Wide-Moat/open-computer-use/issues/161)); not enforced in v1 | k6 perf gate | Firecracker-Lambda public baseline |
87
+ | NFR-PERF-10 | Audit-pipeline backpressure | ≥10× peak; zero chain breaks; no silent drop | chaos test | RFC-9162 + EU AI Act Art. 12 |
88
+ | NFR-PERF-11 | Egress trust-edge throughput ceiling | `tbd` (`arch/egress-throughput-ceiling`) | — | open |
89
+ | NFR-PERF-12 | Concurrent sandbox count per node per tier | `tbd` (`arch/sandbox-density-per-node`) | — | open |
90
+ | NFR-PERF-13 | Perf regression vs last-green baseline | >10% fails CI | k6 smoke per PR | `CLAUDE.md` CI gates |
91
+
92
+ ## 3. Interaction Capability
93
+
94
+ | ID | Scenario | Target | Verification | Source |
95
+ |---|---|---|---|---|
96
+ | NFR-IC-01 | Human-oversight notification latency | p99 ≤1 s | synthetic test | EU AI Act Art. 14 |
97
+ | NFR-IC-02 | Every operator / control-plane action via CLI + declarative config — no operator-console UI in v1; OCU's data-plane UI (file preview / artifact render) is in scope per NFR-SEC-82 | no operator-console UI per release (CLI feature-parity); data-plane UI auth targets are in NFR-SEC-82 | CI golden-path | `CLAUDE.md` v1 non-goals; NFR-SEC-82 |
98
+ | NFR-IC-03 | PTY + CDP streaming through single WebSocket per session | stable versioned API; one socket per session | integration test | [`02-layer4-control-plane.md`](../../future-architecture/architecture/02-layer4-control-plane.md) §streaming |
99
+ | NFR-IC-04 | Control-plane RPC surface (session create/destroy/exec/fs) versioned | breaking change requires major version + deprecation header | API-version audit | [`02-layer4-control-plane.md`](../../future-architecture/architecture/02-layer4-control-plane.md) §RPC |
100
+ | NFR-IC-05 | Concurrent tool-call contract — sequential default; explicit parallelism opt-in per skill | contract published per release | API contract test | [`gaps.md`](../../future-architecture/gaps.md) K.4 |
101
+
102
+ ## 4. Reliability
103
+
104
+ | ID | Scenario | Target | Verification | Source |
105
+ |---|---|---|---|---|
106
+ | NFR-REL-01 | Control-plane RTO / RPO | ≤60 min / ≤5 min | quarterly DR exercise | DORA Art. 11/12 + tier-1 baseline |
107
+ | NFR-REL-02 | Compute-plane RTO | ≤30 min new sessions (in-flight non-durable) | quarterly DR exercise | DORA Art. 12 |
108
+ | NFR-REL-03 | Audit-pipeline RTO / RPO | ≤15 min / 0 (no event loss) | chaos test | RFC-9162 + DORA Art. 19 |
109
+ | NFR-REL-04 | **[REVISIT — non-gating]** LLM upstream failover | ≤5 min unhealthy → secondary | chaos test | DORA Art. 29 |
110
+ | NFR-REL-05 | Single-AZ failure | continuity across remaining AZs, no operator action | quarterly chaos | DORA Art. 12 |
111
+ | NFR-REL-06 | Regional failure | RTO ≤4 h secondary region (CIF tier) | annual DR exercise | DORA Art. 12 + CPMI-IOSCO baseline |
112
+ | NFR-REL-07 | Routine upgrade — zero customer-visible downtime | per release | release notes | FFIEC BCM |
113
+ | NFR-REL-08 | Stateful sandbox hibernation + resume + snapshot + fork | demonstrated end-to-end | integration test | [`gaps.md`](../../future-architecture/gaps.md) J |
114
+ | NFR-REL-09 | Idle reaper + graceful cleanup reconcile loop | zero orphan processes per release | release acceptance | [`antipatterns.md`](../../future-architecture/antipatterns.md) A15 |
115
+ | NFR-REL-10 | Backup-isolation | physically AND logically segregated from source | architectural review | DORA Art. 12(3) verbatim |
116
+ | NFR-REL-11 | Cooperative shutdown | `terminationGracePeriodSeconds=30`; SIGTERM→5s→SIGKILL; tmpdir clean ≤10 s | integration test | [`antipatterns.md`](../../future-architecture/antipatterns.md) A15 |
117
+ | NFR-REL-12 | Audit producers write only via durable bus; no synchronous DB writes on critical path | bus on path for every event | chaos test | [`10-observability.md`](../../future-architecture/architecture/10-observability.md) §pipeline |
118
+
119
+ ## 5. Security
120
+
121
+ | ID | Scenario | Threats | Target | Verification | Source |
122
+ |---|---|---|---|---|---|
123
+ | NFR-SEC-01 | Kill switch — one session or all globally | DoS, runaway-agent | ≤30 s p99 wall-clock; SOAR webhook + admin API + CLI | chaos test | primitives-backlog |
124
+ | NFR-SEC-02 | Sandbox escape | EoP, Tampering | Tier-appropriate sandbox-escape resistance: gVisor user-space kernel as v1 hardened default; microVM hardware-virt post-v1 ([`arch/microvm-tier-v1.1`](https://github.com/Wide-Moat/open-computer-use/issues/161)). Every tier carries seccomp BPF + Landlock + cap-drop ALL with minimum add-back + read-only rootfs. The host-side Storage broker runs at this same hardened-`runc` floor, profile-independent — it executes no agent-issued code, so it carries no `workload_trust_profile` tier axis (that axis is the sandbox's, NFR-SEC-38) and no separate tier ladder; its blast-radius is bounded by the credential substrate (NFR-SEC-60 / SEC-25) and host-peer accept (NFR-SEC-76). Zero red-team pass per release per tier shipped | red-team suite | EU AI Act Art. 15(5) |
125
+ | NFR-SEC-03 | Audit-log tamper | Tampering, Repudiation | hash-chained append-only audit log; daily Merkle head over the chain submitted to a transparency log within 24 h. Submission envelope signed with a host-local key on the solo / dev tier; the same envelope signed with an HSM-rooted key (PKCS#11 / KMIP) when customer KMS is wired per NFR-FLEX-04. The transparency-log operator signs the Merkle head — we sign only the envelope | daily transparency-log probe; HSM-signature check when customer KMS is wired | RFC-9162 + EU AI Act Art. 12 |
126
+ | NFR-SEC-04 | Credential / key rotation | Information Disclosure | tenant DEK ≤90 d; KEK ≤365 d; revocation ≤5 min platform-wide | rotation audit | PCI-DSS 4.0 Req 3.7 |
127
+ | NFR-SEC-05 | Single forward-proxy egress for guest-internet / upstream-API traffic (the egress-wide-bump rung injects on a per-deployment CA, NFR-FLEX-15); the broker-originated storage-backend leg is a distinct egress purpose served by the same outbound-mediation edge on a pass-through storage lane ([NFR-SEC-85](../manifesto/02-nfrs.md)), not a second uncontrolled outbound | Information Disclosure, exfil | single forward proxy for the guest-egress purpose; per-deployment CA in the sandbox trust store at the bump rung; WebSocket support; ext_authz hook; strict upstream TLS validation + fail-closed; the storage lane terminates no TLS and injects no credential | integration test | primitives-backlog |
128
+ | NFR-SEC-06 | Replay-bundle completeness | Repudiation, forensics | ≥99% session events reconstructable; 100% sessions bundled | replay-eval suite | EU AI Act Art. 12 |
129
+ | NFR-SEC-07 | Supply-chain | Tampering, supply-chain | CycloneDX SBOM + SPDX + SLSA L3 + cosign per release; VEX per known CVE | CI gate | NIST 800-218A |
130
+ | NFR-SEC-08 | Egress allow-list (policy) — the customer declares which outbound destinations are reachable; everything else is denied | Information Disclosure, lateral | Egress trust-edge enforces a customer-declared allow-list, deny-by-default, with auditable denials (enforced at connect time on resolved IP + SNI per NFR-SEC-17). Destination type (LLM API, MCP server, object store, internal API) is not a separate control — each is one allow-listed destination | SIEM-side check | primitives-backlog |
131
+ | NFR-SEC-09 | Identity binding to every action | Spoofing, Repudiation | SPIFFE SVID on every inter-component call; human action requires OIDC + SCIM on the full shelf (a SAML-only customer IdP federates in through Dex or Keycloak, never an OCU SAML surface), a host-rooted local operator credential on the minimal shelf; no anonymous paths and no shared service accounts on either shelf | code-path audit + SOC 2 CC6.x | NYDFS Part 500 |
132
+ | NFR-SEC-10 | Per-session session JWT (session-identity, Control plane → guest; not an upstream credential) | Replay, token-theft | `exp ≤ 60 min` per token — an anti-replay window, not a session control; while the session is active the Control plane issues a fresh token before expiry (rotation, not extension — a stolen token dies in ≤60 min); session length is bounded by the idle and absolute limits (NFR-SEC-40 / NFR-SEC-41), not by this TTL. The ≤60 min value is an engineering bound, not a regulatory one | token-lifetime test | [`antipatterns.md`](../../future-architecture/antipatterns.md) A8 |
133
+ | NFR-SEC-11 | Session JWT signing-key rotation | Tampering | Ed25519, ≤90 d, `kid` header, 24 h overlap | rotation log | [`antipatterns.md`](../../future-architecture/antipatterns.md) A33 |
134
+ | NFR-SEC-12 | DNS-rebinding defence at proxy | SSRF | proxy-owned resolver; fixed mandatory deny-set RFC1918 + RFC4193 (fc00::/7) + RFC4291 link-local (fe80::/10) + `169.254.169.254` + `[fd00:ec2::254]`; filter at connect time on resolved IP + SNI, never DNS resolution. Control-plane and Storage-broker endpoints are never resolved inside the guest — they are reached over the host-opened off-network channel (NFR-SEC-43), so no guest-side name lookup exists to rebind; on the egress path the proxy-owned resolver is the sole resolution authority and a guest-supplied A/AAAA cannot override it for an egress destination (closes in-guest DNS-rebind) | unit test per rejection class; in-guest rebind negative test (a guest-resolved control/broker name cannot retarget the host channel; a guest-supplied A/AAAA cannot override the proxy resolver for an egress destination) | [`antipatterns.md`](../../future-architecture/antipatterns.md) A24 |
135
+ | NFR-SEC-13 | Per-session KMS-backed key destroyed on session end | PVC-reuse cross-tenant | KMS key per session; destroyed on session end | audit destroy-events | [`antipatterns.md`](../../future-architecture/antipatterns.md) A34 |
136
+ | NFR-SEC-14 | Sandbox hardening — `no-new-privileges:true` + cap-drop ALL with minimal add-back + seccomp BPF + read-only rootfs + tmpfs + user-namespace mapping (host UID 0 ≠ container UID 0) + pids/cpu/mem cgroup limits + `docker.sock` not mounted | EoP | invariant per container | admission gate | [`07-security.md`](../../future-architecture/architecture/07-security.md) §container hardening |
137
+ | NFR-SEC-15 | User-data volume-only; image carries no PII | Information Disclosure | `/home/assistant/` volume <1 MB enforced in CI | CI gate | `tests/test-docker-image.sh` |
138
+ | NFR-SEC-16 | Installer and runtime never call Wide-Moat-controlled endpoints without explicit customer opt-in; outbound traffic permitted only to endpoints the customer configured (LLM upstream API, customer SIEM, customer S3, customer DNS, customer registry — up to 5 named categories per deployment, documented in release notes); telemetry / error reporting / update checks default off. Each category is reached over the outbound-mediation edge on the purpose that governs its traffic class — guest-internet / upstream-API on the forward-proxy purpose (NFR-SEC-05), customer object storage on the storage lane ([NFR-SEC-85](../manifesto/02-nfrs.md)) — both deny-by-default and audited; this forbids vendor-callback and any ungoverned exit, not a second governed purpose | Information Disclosure | zero Wide-Moat-controlled outbound in default config; every outbound path is to a customer-configured category and is audited; opt-in feature flags surface telemetry; release notes enumerate customer-configured endpoint categories | CI artifact inspection (installer + runtime images) | primitives-backlog |
139
+ | NFR-SEC-17 | Egress allow-list enforcement mechanism — how the NFR-SEC-08 allow-list is applied at the trust-edge | Information Disclosure, exfil | default-deny + allowlist-on-connect (resolved IP + SNI) + `x-deny-reason` block reason. This is the connect-time enforcement of the NFR-SEC-08 policy; distinct from the egress *posture* (the §7 rung ladder, NFR-FLEX-15) | NetworkPolicy diff | [`design-notes.md`](../../future-architecture/design-notes.md) DN-1 |
140
+ | NFR-SEC-18 | Static-tagged image refs; admission rejects unsigned; reproducible-build CI gate | Supply-chain, Tampering | every image ref `@sha256:`; cosign verify at admission; "build twice → digests match" | admission + CI gate | [`antipatterns.md`](../../future-architecture/antipatterns.md) A11 |
141
+ | NFR-SEC-19 | Zero secrets in source | Information Disclosure | gitleaks + trufflehog exit 1 on any finding | `.github/workflows/security.yml` | `CLAUDE.md` top-3 CI gate |
142
+ | NFR-SEC-20 | SAST/SCA CRITICAL blocks merge; HIGH tracked ≤14 d | Tampering, Information Disclosure | CRITICAL = exit 1; HIGH exception ledger | `.github/workflows/security.yml` | `CLAUDE.md` top-3 CI gate |
143
+ | NFR-SEC-21 | **[REVISIT — non-gating]** EU AI Act Art. 15(5) candidate test suite | Tampering, Information Disclosure | pass/fail per release; four named attack classes (data poisoning, model poisoning, adversarial examples, confidentiality attacks); mitigation thresholds tracked against forthcoming EU Commission implementing act | red-team suite | EU AI Act Art. 15(5) verbatim |
144
+ | NFR-SEC-22 | Per-tenant network isolation; inter-sandbox communication disabled by default | Information Disclosure, lateral | tenant-A cannot reach tenant-B sandbox without explicit policy | NetworkPolicy + integration test | [`08-networking.md`](../../future-architecture/architecture/08-networking.md) §isolation |
145
+ | NFR-SEC-23 | The real upstream credential is attached at the Egress trust-edge on the outbound leg, never delivered into the guest. The credential reaches the edge over Envoy SDS from a static file (solo) or a customer-provided SDS-compatible store (enterprise); OCU stores, mints, and rotates nothing (ADR-0005). The storage-backend credential is held by the Storage broker, not here (NFR-SEC-25). "Never in the guest" scopes the *real upstream secret* (the long-lived API key, the backend storage key) — a guest may hold a short-lived, session-scoped handle to a host-side mediator (the Storage-broker resource handle, NFR-SEC-25; a session identity token, NFR-SEC-10), which is not the upstream secret | Information Disclosure | no long-lived upstream key in the container manifest or the guest (disk, env, memory); any guest-held token is session-scoped, short-lived, and not the upstream credential; ≤60 min generic internal token; the upstream credential's own TTL and revocation are the SDS source's | image scan + in-guest secret scan + integration | ADR-0005 |
146
+ | NFR-SEC-24 | When `SkillProvider` lands (post-v1), skills execute inside the same VM boundary as guest workload; no privileged path outside the sandbox | Tampering, supply-chain | invariant carried by component spec when skill registry is in scope; not GA in v1 (see NFR-FLEX-05) | architectural review on `SkillProvider` ADR | primitives-backlog (SkillProvider TBD) |
147
+ | NFR-SEC-25 | No host bind-mount of a secret into the guest, and no secret reaches the guest by any path. The guest speaks a file-operation interface to the host-side Storage broker (its own trust zone, [`02-trust-boundaries.md`](../02-trust-boundaries.md) §2 zone 2), not the object-store protocol; the broker is the object-store client and signs its own backend requests, so no middlebox rewrites a request signature. A storage mount carries only a session-scoped resource handle (e.g. a `filesystem_id`); the backend credential — STS-scoped per session to the prefix the handle names, never a static key — is held by the broker. The backend engine sits behind the broker as a pluggable adapter the guest never sees ([ADR-0010](../adr/0010-storage-backend-pluggable-adapter.md)): a local-volume engine has no network leg, so the broker reaches it by host file I/O and no egress transit applies; a network engine leg is broker-originated and traverses the Egress trust-edge as one allow-list destination, in allow-list-only mode (no TLS termination) so the signature stays intact, and a direct broker-to-backend network dial bypassing the edge is forbidden (NFR-SEC-16). Mount substrate (FUSE / virtio-fs / 9p) is a component-spec choice | Information Disclosure | zero host-side secret bind-mounts; zero upstream credential in the guest; the guest holds at most a session-scoped resource handle | runtime audit + in-guest secret scan | [`06-storage.md`](../../future-architecture/architecture/06-storage.md) §mounts + [`04b-credential-broker.md`](../../future-architecture/architecture/04b-credential-broker.md) |
148
+ | NFR-SEC-26 | Internal service-to-service identity = Ed25519 JWT on WebSocket bound to `container_name` | Spoofing | works identically across all supported runtimes; transport choice (TCP / UDS / vsock) is a deployment-overlay detail, not a platform-level NFR; intra-platform TLS is enforced at the deployment overlay (k8s service-mesh, Compose internal network, microVM vsock) — see Open Question | integration test per runtime | [`02-layer4-control-plane.md`](../../future-architecture/architecture/02-layer4-control-plane.md) §auth + [`05-layer1-guest-agent.md`](../../future-architecture/architecture/05-layer1-guest-agent.md) |
149
+ | NFR-SEC-27 | Egress identity = **network-bound** — the guest sandbox has no route out other than the Egress trust-edge (the host-side broker→backend leg is governed by NFR-SEC-25 and NFR-SEC-85, not this row); the guest's request carries no real upstream credential, and the edge attaches the upstream authorization received over SDS on the re-originated leg | Spoofing | `curl` from sandbox reaches an allow-listed upstream and returns 200 with no long-lived upstream key present in the guest (disk, env, memory) — a session-scoped handle to a host-side mediator, if any, is not the upstream credential (NFR-SEC-23); outbound default-route = the edge | network-policy audit + in-guest secret scan + integration test | [`08-networking.md`](../../future-architecture/architecture/08-networking.md) §egress |
150
+ | NFR-SEC-28 | Wide-Moat ships a default image and a FIPS-validated image variant. Default uses Apache-2.0 crypto providers and supports TLS 1.3 with ChaCha20 + Ed25519. FIPS variant uses FIPS 140-3 validated crypto modules and may carry a narrower cipher floor (e.g. TLS 1.2). Security envelope is equivalent — FIPS variant adds regulator-acceptable certification, not stronger crypto. Two-image stance rationale tracked in `arch/adr-fips-binary-tier` | (compliance) | per-release default + FIPS variants emitted; FIPS-conformance test green on FIPS variant | release-pipeline | separate-binary precedent across enterprise OSS |
151
+ | NFR-SEC-29 | The Egress trust-edge receives a scoped upstream credential over Envoy SDS at injection time; the guest has no channel to the SDS source and never receives a credential. The credential's scope, TTL, mint, rotation, and revocation are the SDS source's — a customer store (enterprise) or a static file (solo), per ADR-0005; OCU runs no credential-minting service | Information Disclosure | the guest holds no upstream credential (in-guest secret scan); the edge attaches it only on the edge-originated upstream leg and holds none at rest; a denylisted session receives no injection independent of the credential's own TTL | per-tier deployment audit + edge integration test | ADR-0005 |
152
+ | NFR-SEC-30 | The Egress trust-edge originates the upstream connection and terminates outbound TLS with strict cert validation, fail-closed; this is the point at which the upstream authorization is injected | Tampering | edge integration test on bad upstream cert | fail-closed test | [`04b-credential-broker.md`](../../future-architecture/architecture/04b-credential-broker.md) §TLS |
153
+ | NFR-SEC-31 | Per-session filesystem-prefix isolation enforced at the Storage broker against the host-attested session identity, not against a guest-presented token | Information Disclosure | cross-session reads architecturally impossible, not policy-guarded | broker integration test | NFR-SEC-25 |
154
+ | NFR-SEC-32 | In-VM memory is NOT a secret store — `/proc/N/mem` readable by in-VM root; defence rests on scope + TTL + external boundary | Information Disclosure | no row of §02 implies in-memory secrecy without external boundary | architectural review | [`07-security.md`](../../future-architecture/architecture/07-security.md) §memory boundary |
155
+ | NFR-SEC-33 | Encryption defaults | (compliance) | TLS 1.3 in transit (TLS 1.2 disable-able); AES-256-GCM at rest; cryptographic erasure of in-session data is per-session DEK destruction at teardown (NFR-SEC-13, NFR-SEC-54) — OCU holds no customer file bytes past the session, so long-term-store erasure is the customer's | per-release crypto conformance | [`07-security.md`](../../future-architecture/architecture/07-security.md) §encryption |
156
+ | NFR-SEC-34 | Continuous eval / red-team in CI | Tampering, Information Disclosure | 10-min red-team subset per PR; full red-team suite nightly; signed attestation per release | per-PR + nightly + per-release | `CLAUDE.md` CI ruleset |
157
+ | NFR-SEC-35 | Host kernel floor + microVM kernel cmdline hardening | EoP, kernel CVEs | Host kernel ≥5.10. KVM presence is a precondition for the microVM tier only (post-v1, [`arch/microvm-tier-v1.1`](https://github.com/Wide-Moat/open-computer-use/issues/161)); when present, microVM-tier templates boot with `init_on_free=1`, `nomodule`, `random.trust_cpu=1`, `panic=1`. KVM absence is not a deployment block; the deployment selects the highest tier the host substrate supports | Helm pre-install probe runs in ≤2 s and emits a clear error naming the missing capability when `runtime: microVM` is configured on a host without `/dev/kvm`; CI test on a KVM-absent runner asserts the probe error path; image-spec audit covers the microVM-tier kernel cmdline | [`04-layer2-runtimes.md`](../../future-architecture/architecture/04-layer2-runtimes.md) §kernel |
158
+ | NFR-SEC-36 | Guest control-plane port unreachable from guest workload code (block-local-connections equivalent on the L1 agent) | EoP, lateral | enforced at L1 listener config + iptables/nftables guest-egress rule | integration test | [`05-layer1-guest-agent.md`](../../future-architecture/architecture/05-layer1-guest-agent.md) §listener |
159
+ | NFR-SEC-37 | Inter-component traffic between Wide-Moat components is encrypted in transit | Information Disclosure, lateral | zero plaintext between named components per release. Documented exceptions (decrypted traffic exists by design and is re-encrypted on the upstream leg): (a) the Egress trust-edge inspection point at the egress-wide-bump rung (NFR-FLEX-15) — absent at the transparent pass-through and deny-all rungs; (b) the DLP-ICAP hook (NFR-COMP-28). Substrate-specific enforcement is a component-spec choice | tcpdump probe on every named inter-component pair captures zero plaintext payload bytes outside (a)/(b); CI gate fails on any plaintext byte outside the carve-out | [`07-security.md`](../../future-architecture/architecture/07-security.md) §intra-platform TLS |
160
+ | NFR-SEC-38 | Workload-trust profile declared at deployment time; admission validates the configured runtime tier against the profile. Allowed pairings: `trusted_operator` → runc / gVisor / microVM; `internal_workforce` → gVisor / microVM; `untrusted` → microVM only. Mismatch is a hard error. Picking the tier by data classification is forbidden separately by AP-13 | Spoofing, Tampering | admission-time validation against a 9-cell pairing matrix. 6 cells valid by pairing rules (3 require the post-v1 microVM tier per [#161](https://github.com/Wide-Moat/open-computer-use/issues/161)); 3 cells rejected by pairing rules. v1 GA deployable: 3 cells (`trusted_operator`×runc, `trusted_operator`×gVisor, `internal_workforce`×gVisor); v1 GA rejected: 6 cells (3 pairing-rejected + 3 microVM-not-shipped) | per-release admission test fixture | [#163](https://github.com/Wide-Moat/open-computer-use/issues/163) |
161
+ | NFR-SEC-39 | Tier-downgrade alarm — a deployment reconfigured from gVisor or microVM to a weaker tier, OR `workload_trust_profile` downgraded with active sessions present | Tampering, Repudiation | audit event `config.trust_profile.downgraded` within ≤30 s; SIEM-bridge HIGH; SOAR webhook per NFR-COMP-27 (one instance of the NFR-SEC-45 enumerated privileged-action set; this row adds the ≤30 s SLA and the active-sessions trigger) | integration test against the audit pipeline | [#163](https://github.com/Wide-Moat/open-computer-use/issues/163) |
162
+ | NFR-SEC-40 | Session idle / inactivity timeout — a session with no activity for the idle window forces re-authentication | Replay, hijack of an unattended session | idle window ≤15 min (configurable down, not up on the full shelf); on expiry the session is terminated and the next call requires re-auth | idle-timeout integration test | PCI-DSS 4.0 Req 8.2.8 + NIST SP 800-63B-4 §2.3.3 (AAL3) |
163
+ | NFR-SEC-41 | Absolute session lifetime — total session duration is capped regardless of activity, forcing periodic re-authentication | Long-lived-session compromise | absolute cap ≤12 h; on expiry the session ends and re-auth is required even if active. Default off on the minimal shelf (solo); on and customer-tunable on the full shelf | session-lifetime integration test | NIST SP 800-63B-4 §2.3.3 (AAL3 SHALL ≤12 h) |
164
+ | NFR-SEC-42 | **[v2 — `status: tbd`]** Skill-registry supply chain (pairs with the `SkillProvider` of NFR-SEC-24). An author-uploaded skill is signed server-side at ingest; provenance (author, time, who enabled it) is a first-class audit record; the signature is verified at attach, so content cannot change between sign and mount; a signature binds the skill to its author (accountability). Post-sign substitution is rejected | Tampering, supply-chain, Repudiation | commitment for the SkillProvider component spec; not GA in v1. When in scope: server-side signature at upload, signature-verified attach (reject on mismatch), provenance audit event per upload + per enablement | architectural review on the `SkillProvider` ADR | [#179](https://github.com/Wide-Moat/open-computer-use/issues/179) |
165
+ | NFR-SEC-43 | Control / exec channel stays off any guest-reachable network: the host opens it, the guest listens, over vsock (microVM) or a host-side unix socket (`gVisor` / `runc`); a TCP listener rejects loopback + own-interface sources. Every host-facing guest call (Control plane, Storage broker) is attributed by a host-derived identity — hypervisor context id, kernel peer credentials of the per-session sandbox principal, or a per-session socket path the guest cannot enumerate — never a session/tenant id the guest supplies. A guest-out reverse dial is a fallback only where a host-reachable guest listener is unavailable; the bridge then holds no credential, runs unprivileged + syscall-confined, and authenticates the session before any privileged action | Spoofing, Elevation of Privilege | guest-originated code cannot reach the control channel via its own network stack; a guest with in-sandbox root cannot present another session's identity; guest-supplied identity is rejected as authoritative | integration test (guest-stack dial to control listener fails; forge-another-session attempt fails) + bridge privilege/seccomp review | [`02-trust-boundaries.md`](../02-trust-boundaries.md) §4 |
166
+ | NFR-SEC-44 | A snapshot/hibernation image is a verbatim copy of guest RAM + disk: any session secret live at snapshot time is frozen into a file that can be copied and booted where the resume hook never runs. **Primary:** no session-scoped secret is present in guest RAM or disk at snapshot-create time — the image is taken at minimal-init (generic template) before session identity/rootfs is layered, and session material is hot-swapped only at restore. **Secondary:** on resume the kernel CSPRNG is reseeded (VMGenID) with no session crypto before the generation-ID change is observed, the guest re-authenticates for fresh host-attested identity (NFR-SEC-43), and userspace identity/nonce/RNG reset; no two guests restored from one image present the same token, nonce, or RNG stream | Information Disclosure, Spoofing, EoP (multi-resume replay) | offline extraction of the memory file + disk backing scanning for token/key/lease byte patterns finds none; booting one image N× yields a distinct host-attested identity and distinct `getrandom()` stream per guest; a token recovered from a stubbed-resume offline boot is rejected by the broker (host-side revoke) | offline image-extraction scan gate; N-fork uniqueness test; negative test (stub resume hook, boot a copied image, attempt token reuse → rejected) | Firecracker `snapshot-support.md` §snapshot-security + `random-for-clones.md`; UAPI VMGenID spec; arXiv 2102.12892; NIST SP 800-190 §4.5; [#184](https://github.com/Wide-Moat/open-computer-use/issues/184) |
167
+ | NFR-SEC-45 | Mandatory audit of every privileged control-plane action (enumerated set, not only tier-downgrade): force-kill, denylist edit, quota override, retention-policy change, any state-mutating operator or SOAR call (trust-profile downgrade is covered with its ≤30 s SLA by NFR-SEC-39). Each emits an OCSF event into the hash-chained pipeline (NFR-SEC-03) under host-attested operator identity (NFR-SEC-09), fail-closed (action denied if audit write fails) | Repudiation, Tampering | 100% of enumerated privileged actions emit a chain-linked OCSF event before acknowledgement; zero successful privileged action with no record; enumerated set is a versioned fixture | per-release integration test drives every enumerated action + asserts a matching record; negative test asserts deny on audit-sink failure | NYDFS §500.6, DORA Art.10, EU AI Act Art.12/14; [#186](https://github.com/Wide-Moat/open-computer-use/issues/186) |
168
+ | NFR-SEC-46 | Per-sandbox resource-exhaustion containment beyond the PID/CPU/mem ceiling (NFR-SEC-14): disk quota on scratch + broker mount/prefix bytes; deterministic OOM scoping (`memory.oom.group=1`, the breaching sandbox is the victim); the Storage broker and Egress edge each rate-limit per host-attested session (file-ops/s, in-flight bytes, fd; new-conn/s, concurrent-conn); the file-operation transport caps max-message and max-object (read/write) size and any transfer above the single-message ceiling MUST be chunked — an over-size frame is rejected before buffering, never partially staged (closes P4-T1/P4-D1) | DoS (noisy-neighbour) | a flood from one sandbox keeps co-resident sandboxes, the shared broker, and the shared edge within ≤10% p99-latency regression against the NFR-PERF baseline; the offender is the deterministic OOM/quota victim (the containment breach itself is audited per NFR-SEC-72); a broker request or object exceeding the configured ceiling is rejected pre-buffer with a structured deny, and no single frame allocates broker memory beyond the message cap | red-team noisy-neighbour suite (disk-fill, fork+fd, broker file-op flood, egress conn flood) per tier asserting co-tenant SLO held + offender contained; broker over-size suite (single oversized message, oversized object without chunking, chunk-count abuse) asserts pre-buffer reject and bounded per-frame allocation | EU AI Act Art.15(4), DORA Art.6/28, CCM IVS-06/09; [#188](https://github.com/Wide-Moat/open-computer-use/issues/188) |
169
+ | NFR-SEC-47 | Out-of-band audit source for in-sandbox actions — the guest is never the authoritative author of its own audit events; in-sandbox tool calls/results are recorded by the host-side mediation layer that issues the call, and on the `gVisor` and microVM tiers a runtime-monitor trace session (gVisor seccheck remote sink / microVM behavioral capture) established at sandbox init before guest code runs and not disableable from inside the guest | Repudiation | 100% of mediated tool invocations have a host-authored record independent of any guest-emitted event; runtime-monitor session present from container start in 100% of sessions; a hostile PID-1 cannot suppress/forge the host-authored record (zero red-team pass per tier per release) | red-team suppression test + audit-completeness diff (host-authored vs guest-emitted) + session-init presence check in CI | OCSF, NIST SP 800-92; [#181](https://github.com/Wide-Moat/open-computer-use/issues/181) |
170
+ | NFR-SEC-48 | Host-side trusted-time floor — all TTL and revocation decisions (session JWT, storage handle, denylist windows) computed against a monotonic clock immune to wall-clock setback; the wall-clock anchor is synchronised via authenticated time (NTS/Roughtime or platform-attested), unauthenticated NTP rejected; the audit envelope (NFR-SEC-03) carries a monotonic sequence plus trusted wall-clock and the Merkle-head cadence is keyed off monotonic time | Tampering, Repudiation | a wall-clock setback ≥ a TTL window does not extend any lease/token; spoofed/unauthenticated time injection rejected 100% in test; Merkle-head cadence holds under simulated wall-clock jumps | red-team clock-rollback + spoofed-time-server harness against egress/audit; CI asserts TTL enforcement reads a monotonic source | RFC 8915 (NTS), Roughtime, DORA ICT-integrity; [#185](https://github.com/Wide-Moat/open-computer-use/issues/185) |
171
+ | NFR-SEC-49 | Per-action authorization and minimum lease scope — the gateway evaluates a deny-by-default policy keyed on (authenticated caller, tool name, action parameters) before dispatch, with argument-scoped deny rules even where a tool class is allowed; the SDS-delivered credential for a call is scoped at the source to the action verb and the exact prefix/API-key class the call names, never the wider resource class (structural validity of the call is NFR-SEC-51; this row is the authorization decision on validated input). The storage intent axis has three values — `read`, `write`, `preview`; on `intent=preview` the broker enforces read-only and treats the object as non-downloadable regardless of its stored tag (NFR-SEC-73), minting no egress-eligible artifact and issuing no write lease | Elevation of Privilege | a caller authorized for tool T cannot invoke a denied action variant of T; a session needing read of prefix P gets a lease that cannot write or reach prefix Q (fails at the backend, not only at policy); a `preview`-intent call yields neither a write lease nor a downloadable artifact even on a `downloadable=true` object; zero red-team pass on per-action escalation per release | gateway policy unit + property tests on argument predicates; edge integration test asserting attached-credential scope == requested action scope | NYDFS §500.7, DORA Art.28, NIST 800-207 §2.1, CCM IAM-08/CEK-08; [#187](https://github.com/Wide-Moat/open-computer-use/issues/187) |
172
+ | NFR-SEC-50 | Transport-bound and proof-of-possession upstream credentials are served by edge re-origination, never a guest-held key. Available at the egress-wide-bump rung only (§7, [ADR-0007](../adr/0007-egress-auth-mechanism.md)) — the transparent pass-through rung cannot attach an upstream credential. For client-mTLS / cert-pinning upstreams the Egress edge terminates the guest→edge leg and originates the upstream TLS with a client cert/key supplied by the SDS source at connect time (NFR-SEC-29 delivery discipline); the pin is verified edge-side. For DPoP the SDS source supplies the PoP key and the edge signs each proof at injection. Schemes needing a guest-resident key are declared unsupported, not satisfied by a guest credential | Spoofing, Information Disclosure, EoP | zero client-cert/PoP private-key material in the guest (in-guest secret scan) for any served mTLS/cert-pin/DPoP destination; a destination needing a guest-resident key is rejected at config time with a structured deny | in-guest secret scan + egress integration test (mTLS upstream returns 200 with no cert in guest; DPoP upstream accepts edge-signed proof) + config-time reject test | RFC 9449, NYDFS §500.15, DORA Art.28; extends NFR-SEC-05/27/29; [#176](https://github.com/Wide-Moat/open-computer-use/issues/176) |
173
+ | NFR-SEC-51 | Gateway strict-validates every MCP tool-call against a closed JSON Schema at ingress before any action — reject-unknown-fields, type/length/pattern bounds on `container_name`/`args`/`selector`; malformed input is rejected with a structured deny, never partially acted on. Outbound errors and responses are size-bounded and identifier-minimized: a deny/error carries a stable error class and a correlation id, never session_id, container_name, internal host/route, or stack/internal-path detail; discovery responses expose only the declared tool surface (closes P1-I1) | Tampering, Information Disclosure | 100% of tool-call params schema-validated pre-dispatch; reject-on-unknown-field enforced; 100% of error/response payloads bounded in size and free of internal session/container/route identifiers (allow-list of emitted fields, not a redaction blocklist) | property-based tests on the gateway decoder (NFR-MAINT-11 CI gate) + a schema-conformance negative fixture asserting reject-on-unknown-field; an outbound-leak fixture asserts every error class and discovery response carries no session/container/route identifier and stays within the size bound | NYDFS §500.15, DORA Art.30, EU AI Act Art.13, CCM IAM-08; closes [#149](https://github.com/Wide-Moat/open-computer-use/issues/149) |
174
+ | NFR-SEC-52 | CI IaC-policy assertion that the agent-facing MCP gateway has no network route to the operator/Control-API ingress (kill-switch, denylist, lifecycle), enforced as a deny-by-default rendered-manifest check on both shelves | Elevation of Privilege | rendered deploy manifests (k8s NetworkPolicy + Compose internal network) fail CI if any rule or co-location allows gateway→operator-ingress reachability; negative-reachability holds on minimal and full shelf | Checkov + tfsec + network-policy audit per release | NIST 800-207 §2.1, NYDFS §500.7, EU AI Act Art.14, CCM IAM-06 |
175
+ | NFR-SEC-53 | Per-caller-identity concurrent-connection / fd ceiling at the MCP gateway listener, independent of the per-tenant calls-min and concurrent-session quotas (NFR-COST-06), keyed to the audience-validated caller identity, not source IP | DoS | the gateway holds ≤ N open connections per validated caller; excess refused not queued; a single caller cannot consume > X% of the listener fd table; rejection emitted as an OCSF event | connection-flood chaos test asserts a single-caller flood is refused above N with an OCSF event while a concurrent caller's success is unaffected | NYDFS §500.7, DORA Art.6, CCM IVS-06 |
176
+ | NFR-SEC-54 | Erase-before-reuse ordering on a recycled local mount substrate — a session-2 handle binds to a scratch or broker-cache region only after any session-1 plaintext there is unreadable (zeroized, or its per-session DEK destroyed per NFR-SEC-13 where the local cache is DEK-encrypted); stated substrate-agnostically (FUSE/virtio-fs/9p) | Information Disclosure | zero readable session-1 bytes observable by session-2 across N reuse cycles; erase completes-before re-grant (a happens-before invariant, distinct from the age-driven NFR-COST-07) | property test: write a marker in session-1, recycle the substrate, assert session-2 cannot read it; audit a paired teardown-erase→re-grant ordering | EU AI Act Art.10, CCM DSP-01/DSP-07, NYDFS §500.15(a) |
177
+ | NFR-SEC-55 | Kill-switch / revoke path keeps the NFR-SEC-01 ≤30 s p99 target while the control plane is under concurrent saturation — including a flood on the operator/SOAR ingress itself, not only the agent path; reserved CPU/connection capacity (or admission priority) for the lifecycle/revoke route plus a per-caller quota on the operator+SOAR ingress | DoS | revoke completes ≤30 s p99 under a chaos test running concurrent control-plane DoS (agent-path flood AND operator-ingress flood at the quota ceiling); the single-instance minimal shelf is explicitly in scope | chaos test with an adversarial concurrent-load dimension on revoke latency, co-located with the NFR-SEC-01 test; NFR-REL-01 is the post-failure backstop | DORA Art.6/11, NYDFS §500.7, EU AI Act Art.14, CCM IVS-06 |
178
+ | NFR-SEC-56 | Per-source ingest fairness at the audit fan-in boundary, keyed to the host-attested OCSF source identity (never a guest-settable source field); the broker/edge data-plane rate limits are NFR-SEC-46, this row is the audit-ingest dimension; the retention-budget dimension is tracked separately ([#150](https://github.com/Wide-Moat/open-computer-use/issues/150)) | DoS (event-volume flood / forensic dilution) | no single source consumes > N× its provisioned ingest share within a rolling window; over-share is rate-shaped (not dropped), counted, and itself emits a saturation event; co-tenant sources keep full headroom; the aggregate no-drop / chain integrity of NFR-PERF-10 is preserved | chaos test: one source floods well-formed OCSF at ≥10× its share; assert its admitted rate is capped, co-tenants keep headroom, zero chain breaks | NYDFS §500.6, DORA Art.10, CCM LOG-01/02; [#188](https://github.com/Wide-Moat/open-computer-use/issues/188) |
179
+ | NFR-SEC-57 | Payload-independent exfil tripwire active at every egress rung (no CA required) — a per-session egress-byte budget plus destination-cardinality and rate anomaly emitted to audit and SOAR, independent of TLS termination. **Accept-with-tier:** the transparent pass-through rung stays content-blind; deep content DLP requires the egress-wide-bump rung (NFR-FLEX-15 + NFR-COMP-28) and the buyer formally accepts the content-blind transparent rung in the tier datasheet | Information Disclosure, exfil | the transparent pass-through rung raises a structured OCSF anomaly event (and can arm the kill switch) when a session exceeds its configured egress-byte budget or above-threshold distinct-destination count within window W; p99 detection ≤ NFR-SEC-01 SLA | integration test: scripted exfil of N bytes to an allow-listed sink at the transparent pass-through rung trips the anomaly event and (when armed) the kill switch | NYDFS §500.15, DORA Art.30, EU AI Act Art.15, CCM DSP-05; builds on NFR-COST-06; [#182](https://github.com/Wide-Moat/open-computer-use/issues/182) |
180
+ | NFR-SEC-58 | Cross-tenant microarchitectural side-channel posture, **declared not eliminated.** Shared-kernel (gVisor) tier: the residual is accepted and named in the tier datasheet — no cross-tenant timing guarantee. Hardware-virt/microVM tier and above: per-host SMT disabled, current CPU microcode applied, host kernel hardware-vuln mitigations not disabled, and high-sensitivity sessions schedulable to dedicated cores / single-tenant hosts | Information Disclosure | for a side-channel-reduced tier: 0 sessions land on a host with SMT enabled OR stale microcode; scheduler proves single-tenant pinning for flagged sessions | CI/boot-time host attestation (SMT=off + microcode ≥ baseline + mitigations≠off); scheduler-policy test; tier-datasheet review of the accepted residual | NIST SP 800-125A, CIS host-hardening; [#183](https://github.com/Wide-Moat/open-computer-use/issues/183), [#148](https://github.com/Wide-Moat/open-computer-use/issues/148) |
181
+ | NFR-SEC-59 | The Egress trust-edge process memory is NOT a secret store against a host-root adversary — `/proc/N/mem`, ptrace, core-dump expose a live injected credential on every shelf. Defence rests on (a) the in-sandbox guest having no path to the edge host (NFR-SEC-43/23, SEC-02/14), so this is reachable only off a host foothold; and (b) the edge holding only the SDS-delivered credential transiently at injection, never a root key — the root rests in the SDS source (a customer store HSM-resident on the full shelf, FIPS 140-3 L3, NFR-FLEX-04; a static file on the solo shelf). A credential captured in a RAM snapshot at rest is NFR-SEC-44/#184 | Information Disclosure | minimal shelf: no in-process-memory secrecy claim (host-root = game over, single-tenant `trusted_operator`); full shelf: the root never enters edge-process memory — only the transient injected credential is scrapable | architectural review per release; confidential-computing (SEV-SNP/TDX) deferred as optional | NIST 800-57, DORA Art.28, CCM CEK-08 |
182
+ | NFR-SEC-60 | The minimal-shelf Storage broker MAY hold a long-lived host-local backend credential in place of the NFR-SEC-25 STS-scoped-per-session credential ONLY where `workload_trust_profile = trusted_operator` and the deployment is single-tenant; admission MUST reject a long-lived broker credential under any other profile or any multi-tenant agent-execution deployment, where NFR-SEC-25 STS-scoped-per-session is mandatory; a local-volume backend engine ([ADR-0010](../adr/0010-storage-backend-pluggable-adapter.md)) exercises a host filesystem permission, not a network credential | Spoofing, Information Disclosure | zero long-lived broker backend credential admitted outside single-tenant `trusted_operator`; the minimal-shelf credential is scoped to exactly one backend scope (a bucket prefix for a network engine, a host path for a local-volume engine) | per-profile admission test (long-lived cred + non-`trusted_operator` OR multi-tenant = reject), reusing the NFR-SEC-38 pairing check | NFR-SEC-25 + SEC-38 + SEC-31; DORA Art.28, NYDFS §500.15(a), CCM CEK-08 |
183
+ | NFR-SEC-61 | Snapshot/hibernation artifacts (memory file, disk backing, state file) are encrypted and integrity-authenticated at rest; restore rejects an artifact whose authentication tag does not verify (a CRC is anti-corruption, not a security control) | Information Disclosure, Tampering | memory/disk/state artifacts AES-256-GCM at rest (NFR-SEC-33); a tampered or unauthenticated image is rejected at load, not booted; zero plaintext secret recoverable from an artifact at rest | offline read of an artifact yields ciphertext only; a bit-flipped artifact fails authentication and is refused at restore | NIST SP 800-190 §4.5; extends NFR-SEC-33; [#184](https://github.com/Wide-Moat/open-computer-use/issues/184) |
184
+ | NFR-SEC-62 | A runtime guard admits at most one restore of a unique-state-bearing snapshot — the single-restore primitive that backs the NFR-SEC-44 fork-uniqueness invariant (SEC-44 owns the distinct-identity/entropy-per-fork guarantee; this row prevents the multi-restore that would force it) | EoP (multi-resume replay) | a second restore of the same unique-state-bearing image is refused at the runtime; the guard is host-side, not guest-cooperative | attempt a second concurrent restore of one image → refused | Firecracker `random-for-clones.md`; arXiv 2102.12892; backs NFR-SEC-44 |
185
+ | NFR-SEC-63 | On resume, the wall clock is corrected before any time-bound check runs — a snapshot freezes `CLOCK_REALTIME`, so token `exp`/`nbf`, TLS cert validity, lease TTL, and audit ordering would otherwise be evaluated against stale time | Tampering, Repudiation | no time-bound validation (JWT exp/nbf, TLS validity, lease TTL, audit timestamp) executes on resume until the wall clock is re-synced against the trusted-time source (NFR-SEC-48); a frozen-clock window cannot accept an expired token or order events wrongly | resume a snapshot taken > a TTL window earlier; assert the pre-snapshot token is rejected and audit ordering uses corrected time | pairs NFR-SEC-48; NIST SP 800-190 §4.5; [#185](https://github.com/Wide-Moat/open-computer-use/issues/185) |
186
+ | NFR-SEC-64 | On resume or warm-restore, prior-session page-cache and device-backend residue are not readable by the new session — caches are dropped and hot-swapped backends remounted before the new session runs. This is the volatile-cache control on the resume path; the persistent mount-substrate zeroize-before-grant is NFR-SEC-54 and per-session DEK destruction is NFR-SEC-13 | Information Disclosure | zero prior-session filesystem-cache or device-backend bytes readable by a restored/recycled session; cache drop + backend remount completes-before the new session executes | write a marker in session-1, restore/recycle, assert session-2 cannot read it from cache or a stale backend | OUR-DESIGN; pairs NFR-SEC-54/13; CCM DSP-01 |
187
+ | NFR-SEC-65 | Sandbox teardown on the container tiers (`runc`/`gVisor`, which get no VM-death scrub for free) runs a host-driven ordered finalizer — credentials revoked and writable surfaces scrubbed before the process tree is killed and the cgroup destroyed (revoke session JWT, drop the network-bound egress route per NFR-SEC-27, zero tmpfs/scratch, unmount the data scope, then kill and destroy). No step depends on guest cooperation | Information Disclosure, Repudiation | the finalizer completes credential-revoke + surface-scrub before kill on every stop→destroy of a container-tier sandbox; the outbound route is dropped host-side even if the guest is unresponsive | teardown integration test asserts scrub-before-kill ordering and that a killed/unresponsive guest still has its outbound route dropped host-side | NIST SP 800-190 §4.5; pairs NFR-SEC-43/29; [#184](https://github.com/Wide-Moat/open-computer-use/issues/184) |
188
+ | NFR-SEC-66 | Before a hibernate that retains the image, the agent zeroes its live session-token buffers — `init_on_free` clears freed pages but not live ones, so a token held in a live buffer survives into the retained image | Information Disclosure | zero live session-token bytes in agent-held buffers at the moment the retained image is written; the agent zeroizes on the pre-freeze hook | offline scan of a hibernate image for the agent's live token buffers finds none | OUR-DESIGN; complements NFR-SEC-44 |
189
+ | NFR-SEC-67 | A crashed sandbox is access-gated or sanitized before any reuse or snapshot — the crash path retains the state/log dir and skips the graceful scrub, so crashed-sandbox state must not be reusable or snapshottable un-scrubbed | Information Disclosure | a `running→crashed` sandbox's retained state cannot be reused or snapshotted until sanitized or access-gated; zero crashed-session secret reaches a later session or a snapshot | crash a session mid-run; assert its state dir is access-gated and a reuse/snapshot attempt is refused until scrubbed | OUR-DESIGN; NIST SP 800-190 §4.5 |
190
+ | NFR-SEC-68 | A guest that executed any session is destroyed, never returned to a warm pool — a recycled running guest carries process, memory, tmpfs, and keyring state, not only mount bytes (NFR-SEC-54 covers the mount substrate only) | Information Disclosure | zero post-session guest re-pooled for another tenant; the single-use rule holds at the guest granularity; erase-before-regrant (NFR-SEC-54) remains the substrate-only secondary for the mount | attempt to claim a guest that ran a prior session → refused (destroyed); pool only hands out never-run guests | OUR-DESIGN; extends NFR-SEC-54 |
191
+ | NFR-SEC-69 | At warm-pool claim/hand-off, the guest re-derives a fresh host-attested identity and discards any pre-warm placeholder token / `filesystem_id` — NFR-SEC-43 covers the resume path, not the pool-claim path | Spoofing, EoP | a claimed guest presents a fresh per-tenant host-attested identity (NFR-SEC-43); the pre-warm placeholder JWT/`filesystem_id` is invalid after claim; no tenant inherits a placeholder credential | claim a pre-warmed guest; assert its identity is re-derived and the placeholder token is rejected post-claim | pairs NFR-SEC-43; OUR-DESIGN |
192
+ | NFR-SEC-70 | A poolable unit is provisioned under a non-tenant placeholder identity and carries zero tenant secret or PII before claim — nothing tenant-bound is populated into a unit that has not yet been claimed | Information Disclosure | a pre-claim poolable unit holds no tenant secret/PII and no tenant-bound credential; provisioning uses a placeholder identity only | inspect a pre-claim pooled unit → zero tenant secret/PII; provisioning identity is the placeholder, not a tenant | OUR-DESIGN; the pre-claim half (NFR-SEC-69 is the claim-time re-derivation; NFR-SEC-68 the single-use rule) |
193
+ | NFR-SEC-71 | On boot-from-snapshot, guest unique identifiers (`boot_id`, `machine-id`) are regenerated — otherwise they replay verbatim across every fork of one image. This is the guest-unique-ID member of the fork-uniqueness family: token/nonce/RNG (NFR-SEC-44), single-restore (NFR-SEC-62), guest unique IDs (this row) | Spoofing | `boot_id` and `machine-id` differ across N forks of one snapshot; no guest unique identifier replays from the template | boot one image N×; assert distinct `boot_id`/`machine-id` per guest | UAPI VMGenID spec; Firecracker `random-for-clones.md`; pairs NFR-SEC-44/62 |
194
+ | NFR-SEC-72 | The NFR-SEC-45 audit contract (chain-linked OCSF before ack, versioned fixture, fail-closed, host-attested identity) applied to the system-initiated lifecycle transitions — secret inject/revoke, scrub, snapshot-create, restore, teardown, crash-sanitize, pool-claim. Split by initiator so the two fixtures neither overlap nor gap: operator-initiated privileged actions are SEC-45, system-initiated lifecycle transitions are this row (an operator-forced credential mint is SEC-45; an automatic per-session lease issue is SEC-72) | Repudiation | 100% of the enumerated lifecycle transitions emit a chain-linked OCSF event before the transition is acknowledged; versioned fixture; fail-closed on audit-write failure | per-release integration test drives each transition and asserts a matching hash-chained record; negative test asserts deny/halt on audit-sink failure | extends NFR-SEC-45/03; NYDFS §500.6, EU AI Act Art.12 |
195
+ | NFR-SEC-73 | Storage authorization carries a third axis beyond scope (`filesystem_id`) and intent (`read` / `write` / `preview`, NFR-SEC-49): a per-object/per-prefix `downloadable` tag (default `false` for any class above PUBLIC), resolved broker-side at read. A `downloadable=false` object may be read into the sandbox for in-session use but the broker mints no egress-eligible artifact for it (no scoped/presigned URL, no broker-written copy onto an egress-reachable path) — the engine-independent primary control — and the tag propagates to the Egress trust-edge as a deny signal keyed on the object's content-handle, so an outbound leg that traverses the edge carrying non-downloadable content is denied regardless of destination allow-list membership and regardless of egress rung. Separates "agent may read this object" from "agent may remove it from the sandbox"; the intent verb is NFR-SEC-49, this row is the downloadable axis | Information Disclosure, Elevation of Privilege | a `downloadable=false` object is readable in-session yet zero egress-eligible artifact is minted for it; an attempt to ship its content out is denied at the broker and, if a content-handle reaches the edge, denied there with a structured deny-reason — at every egress rung; an object reclassified to `downloadable=false` mid-session is non-shippable on the next read | broker authz unit + property tests on the three-axis claim (read allowed / artifact-mint denied for the non-downloadable case); edge integration test asserting a non-downloadable content-handle is denied at every egress rung; negative test on mid-session reclassification | OUR-DESIGN (three-axis file-broker claim {scope, intent, downloadable}); pairs NFR-SEC-49 + SEC-25; couples to NFR-SEC-27/57; EU AI Act Art.10, DORA Art.28, NYDFS §500.15(a), CCM DSP-01/DSP-05 |
196
+ | NFR-SEC-74 | The host-side exec supervisor bounds per-stream stdout/stderr volume over the host↔guest exec channel: each stream is a framed, length-prefixed transport with a per-process byte counter; on reaching the per-call ceiling the supervisor stops forwarding, emits a single truncation marker, and records the dropped-byte count — it never buffers unbounded guest output into host memory or the audit pipeline | DoS (host memory-pressure; audit-amplification) | per-call stdout+stderr forwarded to host memory and to the audit sink is bounded by a declared ceiling (default ≤8 MiB/stream, configurable per workload tier); beyond it the call carries a `truncated: true` marker + byte count, never a partial frame; host RSS attributable to one session's stdio stays within the NFR-SEC-46 noisy-neighbour budget (≤10% p99 regression) under a max-rate output flood | red-team output-flood suite (a guest writing unbounded stdout/stderr at line rate) per tier asserting host memory bounded, truncation marker emitted, audit record size capped | OUR-DESIGN (bounded-read idiom — read ceiling+1 to detect overflow, mark-not-OOM); framed length-prefixed stdio transport (gVisor gofer bounded host buffers); pairs NFR-SEC-46; EU AI Act Art.15(4), DORA Art.6, CCM IVS-09; [#188](https://github.com/Wide-Moat/open-computer-use/issues/188) |
197
+ | NFR-SEC-75 | The host derives the spawned guest-process environment from an explicit allowlist, not by inheriting the host environment: at fork the supervisor strips any inherited name matching `*_TOKEN` / `*_SECRET` / `*_PASSWORD` / `API_KEY` (and the configured deny-pattern set) before exec, and injects only the named vars the workload declares; a secret that must reach a tool is passed via the environment or a file descriptor, never on argv, because argv is world-readable through `/proc/<pid>/cmdline` to any same-namespace process | Information Disclosure | 0 host-process secret-bearing env names (deny-pattern set) present in any guest-spawned process environment; 0 secret values present in any guest-visible argv / `/proc/<pid>/cmdline`; env injection is allowlist-only (inherit-none default) | spawn-time fixture asserting the deny-pattern env set is absent and every spawned process argv is secret-free; property-based test over generated env names asserting pattern-strip coverage | OUR-DESIGN (allowlist env injection — host sets only declared vars; secret-as-named-placeholder resolved at the trust edge, never raw in argv); secrets-not-in-argv (CIS Benchmarks / OWASP — `/proc/<pid>/cmdline` world-readable); pairs NFR-SEC-43; NYDFS §500.7, DORA Art.6, CCM IAM-08/IVS-06; [#188](https://github.com/Wide-Moat/open-computer-use/issues/188) |
198
+ | NFR-SEC-76 | The Storage-broker and Control listener accept a connection only from the host: the peer source is checked against the expected host hypervisor context id (microVM) or host kernel peer credentials (`gVisor` / `runc`) and any non-host peer is dropped at accept, before any frame is parsed — this is the accept-time enforcement of the NFR-SEC-43 invariant, not the identity-derivation. For multi-tenant deployments the broker is instantiated per tenant (one broker principal per tenant filesystem scope), not a single multiplexed broker; a multiplexed broker is allowed only for a single-tenant `trusted_operator` shelf | Spoofing, Information Disclosure | a connection from any peer that is not the host CID / host peer-cred is dropped at accept with zero frames parsed; in a multi-tenant deployment, tenant A's guest cannot reach tenant B's broker instance (separate broker principal per tenant) | accept-time negative test (forged non-host peer dropped pre-parse) + multi-tenant isolation test (cross-tenant broker reach fails) | extends NFR-SEC-43; [`02-trust-boundaries.md`](../02-trust-boundaries.md) §2 zone 2; OUR-DESIGN |
199
+ | NFR-SEC-77 | **[microVM tier — [#161](https://github.com/Wide-Moat/open-computer-use/issues/161)]** On the microVM tier, death of the in-guest supervisor / PID-1 forces guest death (`kernel.panic=1`, panic-on-oops, no init to reap orphans), so no headless guest outlives its supervisor while holding a live egress route. On the v1 container tiers (`runc` / `gVisor`) this is accepted: the host-driven ordered finalizer (NFR-SEC-65) drops the outbound route host-side even if the guest is unresponsive, so the residual is a process tree with no route, not a routed orphan | Information Disclosure, Elevation of Privilege | microVM tier: supervisor/PID-1 death triggers guest panic within the kernel panic window, no surviving routed guest; container tiers (v1): an orphaned guest holds no outbound route after NFR-SEC-65 host-side teardown | microVM kill-supervisor test asserts guest panic + route gone (gated on the microVM tier); container-tier orphan test asserts route-dropped host-side | pairs NFR-SEC-65; NIST SP 800-190 §4.5; [#161](https://github.com/Wide-Moat/open-computer-use/issues/161) |
200
+ | NFR-SEC-78 | The data-plane client north-side path (the human/peer file-artifact data plane into the Storage broker) is bounded the same way as the broker south-side mount: the gateway caps inbound request body to a configured maximum (default ≤50 MiB/request, configurable per workload tier) and rejects an over-ceiling body before staging, never partially buffered; per-validated-caller rate limits (file-ops/s, bytes/min) apply distinctly from the per-sandbox quota (NFR-SEC-46) and the per-caller connection ceiling (NFR-SEC-53); the north-side path is served on a dedicated file/UI ingress, not the MCP-tool-call listener that NFR-SEC-53 bounds | DoS (north-side flood, host memory-pressure) | a body above the ceiling is rejected pre-buffer with a structured deny; a single caller's upload/download flood keeps a co-resident caller within ≤10% p99-latency regression against the NFR-PERF baseline; no single request allocates broker memory beyond the configured cap | north-side flood suite (oversized body, body that exceeds the ceiling mid-stream sent without Content-Length, per-caller op/byte flood) asserting pre-buffer reject, bounded per-request allocation, and co-tenant SLO held | OUR-DESIGN (north-face byte-ceiling + pre-buffer-reject); pairs NFR-SEC-46 + NFR-SEC-53; EU AI Act Art.15(4), DORA Art.6/28, CCM IVS-06/09 |
201
+ | NFR-SEC-79 | Every file-activity event on either broker face emits an OCSF File System Activity event into the hash-chained pipeline (NFR-SEC-03) under host-attested identity (NFR-SEC-09), fail-closed (the operation is denied if the audit write fails): the south face (sandbox file-op tool invocations, recorded host-side per NFR-SEC-47) and the north face (data-plane client upload / list / download / delete, gateway-authored — these are not sandbox tool invocations). Mandatory event fields: actor identity, session / `filesystem_id`, operation, object handle, byte count, intent, downloadable disposition, and outcome | Repudiation, Information Disclosure | 100% of file operations on both faces emit a chain-linked OCSF event before the operation response is issued; zero successful file operation with no record; an operation on either face is denied if its audit write fails | per-release integration test drives every file operation on both faces and asserts a matching chain-linked record; negative test asserts deny on audit-sink failure | OUR-DESIGN; extends NFR-SEC-45/47 with a file-activity enumerated set; OCSF File System Activity class (class_uid 1001, OCSF v1.x); NYDFS §500.6, DORA Art.10, EU AI Act Art.12; CCM LOG-01/LOG-02 |
202
+ | NFR-SEC-80 | The broker validates every archive body before extraction: it rejects (a) a declared or computed uncompressed total above a ceiling (default ≤1 GiB, configurable per workload tier) before any entry is extracted — streaming formats with no pre-readable directory are halted when the running byte-count crosses the ceiling mid-extract; (b) any entry whose resolved destination falls outside the named mount path (path traversal); (c) any symlink resolving outside the destination; (d) an entry count above a ceiling (default ≤100 000). Every rejection is pre-extraction, with a structured deny and an OCSF event (NFR-SEC-79) | DoS (decompression bomb), Tampering, Elevation of Privilege (path escape) | a zip-bomb (small body, oversize declared/expanded total) is rejected before extraction or halted at the ceiling mid-extract; a traversal or symlink-escape entry is rejected with zero bytes written outside the destination; an over-count archive is rejected; broker memory/disk during validation stays within the NFR-SEC-46 budget | broker archive suite (decompression-bomb, path-traversal entry, symlink-escape entry, entry-count abuse) asserting pre-extraction reject and zero out-of-destination write | OUR-DESIGN (pre-extraction archive validation); pairs NFR-SEC-46 + NFR-SEC-51; EU AI Act Art.15(4), DORA Art.6, CCM IVS-09/AIS-04 |
203
+ | NFR-SEC-81 | The broker classifies every uploaded body by content on ingest — magic-byte sniff + declared media type — and records the resolved type on the object's metadata before it is visible on any mount; a declared/sniffed mismatch and the resolved type are carried into the OCSF event (NFR-SEC-79). The default posture is classify-and-record; the broker enforces a configurable type allow/deny policy per filesystem scope, and a denied type is rejected pre-stage with a structured deny | Tampering, Elevation of Privilege (staging) | 100% of uploaded bodies carry a broker-resolved content type on metadata before mount-visibility; a declared/sniffed mismatch is recorded and surfaced; a type the scope policy denies is rejected pre-stage with zero bytes written to the mount; with an empty deny policy, 100% of bodies are classified and recorded with zero rejections | broker ingest suite (magic-byte vs declared-type mismatch, polyglot/disguised-extension, denied-type reject, empty-policy classify-and-record) asserting metadata-before-visibility and pre-stage reject on denied types | OUR-DESIGN (classify-and-record ingest, policy-deny opt-in); pairs NFR-SEC-78 + SEC-79; EU AI Act Art.15(4), DORA Art.6, NYDFS §500.15, CCM TVM-02/AIS-04 |
204
+ | NFR-SEC-82 | Embeddable-UI authentication — the peer backend mints a signed short-TTL embed token (OIDC-asserted, `exp ≤ 120 s`); the UI verifies signature + expiry and sets a first-party session; no OCU upstream secret enters the browser. Minimal shelf: pre-issued token, no IdP. Full shelf: OIDC embed via the customer IdP | Spoofing, Information Disclosure, session-fixation | embed token verified before any session state is set; `exp ≤ 120 s` enforced; zero OCU upstream secret in browser storage or any browser-visible response; OIDC embed flow green per release on the full shelf | token-lifetime test (issue + present at boundary; present expired → 401); browser-storage scan (localStorage, sessionStorage, IndexedDB) + response-header scan asserting zero OCU upstream credential in any browser-visible surface; IdP-embed integration test per release | Metabase static-embed signed JWT (≤10 min TTL convention); Looker cookieless tiered tokens; extends NFR-SEC-09 |
205
+ | NFR-SEC-83 | iframe-embedding headers — `Content-Security-Policy: frame-ancestors` set to a per-deployment allowlist on every UI response (header only, never `<meta>`); default `'none'` until configured; `X-Frame-Options: SAMEORIGIN` legacy fallback (CSP-unaware browsers cannot embed cross-origin — accepted degradation); `Cross-Origin-Resource-Policy: cross-origin` on served artifacts; `Cross-Origin-Opener-Policy` not set (preserves `postMessage` to the embedding page). Minimal shelf: `frame-ancestors 'self'` | Clickjacking, cross-origin framing by unauthorized hosts | `frame-ancestors` present on 100% of UI responses; default `'none'` until a configured allowlist entry exists; `X-Frame-Options: SAMEORIGIN` present on every response; `Cross-Origin-Resource-Policy: cross-origin` on artifact responses; zero `Cross-Origin-Opener-Policy` header on UI responses; CI fixture asserts default-deny and allowlist enforcement | response-header fixture asserting default-deny (`'none'`) pre-config and allowlist after config; negative test asserting `<meta>` CSP absent; Cross-Origin-Resource-Policy header-on-artifact assertion | MDN CSP `frame-ancestors`; OWASP Clickjacking Defence Cheat Sheet |
206
+ | NFR-SEC-84 | Browser-session credential — after embed-token verification (NFR-SEC-82) the UI sets a first-party `SameSite=None; Secure; HttpOnly` cookie; every state-mutating request carries a CSRF token validated server-side; no anonymous fallback on a missing or invalid cookie (401, not a guest session). Pairs NFR-SEC-82 | Cross-site request forgery, session-hijack, anon-bypass | 100% of state-mutating requests validated for a CSRF token; a missing/invalid session cookie returns 401 with no anonymous fallback; cookie attributes `SameSite=None; Secure; HttpOnly` enforced on every UI Set-Cookie; zero unauthenticated state-mutating action per release | CSRF integration test (mutating request without token → 403; with valid token → 200); missing-cookie test (→ 401, no anon session); cookie-attribute assertion in response headers; red-team anon-bypass suite per release | OWASP CSRF Prevention Cheat Sheet; Duende BFF first-party cookie pattern; MDN `SameSite` cookie attribute; extends NFR-SEC-09 |
207
+ | NFR-SEC-85 | Storage-egress purpose — a network backend engine's leg is reached over a storage-dedicated lane on the Egress trust-edge, out-of-process from the Storage broker and distinct from the guest egress lane ([ADR-0011](../adr/0011-storage-egress-lane.md)). The broker holds the backend credential, signs each backend request once, and originates the leg; the lane forwards it allow-list-only with no TLS termination (so the signature stays intact, NFR-SEC-25), does no credential injection / CA bump / ICAP, but enforces a deny-by-default destination allow-list at connect on resolved IP + SNI under the one proxy-owned resolver and its mandatory deny-set (NFR-SEC-12), the payload-independent exfil tripwire (NFR-SEC-57), and an edge-authored OCSF event per backend operation (NFR-SEC-79). A direct broker-to-backend dial bypassing the lane is forbidden (NFR-SEC-16). A local-volume backend engine ([ADR-0010](../adr/0010-storage-backend-pluggable-adapter.md)) opens no network leg, so the lane is vacuous for it | Information Disclosure, Elevation of Privilege, Repudiation | a network backend reaches only the configured endpoint(s), every other dial refused at the storage lane before connect; the lane uses the one proxy-owned resolver (zero second resolver admitted); a backend operation emits a chain-linked OCSF event a fully-compromised broker can neither suppress nor backfill; the lane is a listener on the existing edge container (zero new container); a broker dial that bypasses the lane is refused and audited; a local-volume engine opens zero outbound sockets | edge integration test (non-allow-listed backend destination refused pre-connect; broker-bypass dial refused); single-resolver assertion (no storage-lane-owned resolver); compromised-broker negative test (edge-authored backend-op event present and intact when the broker is adversarial); local-volume zero-socket test | pairs NFR-SEC-25 + SEC-12 + SEC-57 + SEC-73 + SEC-79; couples NFR-SEC-05 + SEC-16; DORA Art.28/30, NYDFS §500.15(a), EU AI Act Art.15, CCM DSP-05/IVS-09 |
208
+
209
+ ## 6. Maintainability
210
+
211
+ | ID | Scenario | Target | Verification | Source |
212
+ |---|---|---|---|---|
213
+ | NFR-MAINT-01 | Security-patch SLA | ≤7 d (CVSS ≥9.0); ≤30 d (7.0-8.9); ≤90 d (4.0-6.9) | release-pipeline audit | PCI-DSS 4.0 Req 6.3.3 + banking convention |
214
+ | NFR-MAINT-02 | Upgrade rollback to N-1 | ≤30 min Control plane; ≤5 min Compute plane node | DR exercise | DORA Art. 12 |
215
+ | NFR-MAINT-03 | Configuration drift detection | declarative; ≤5 min divergence | continuous monitoring | NYDFS Part 500 § 500.5 + SOC 2 CC7.x |
216
+ | NFR-MAINT-04 | API deprecation policy | announce N versions before removal; `Deprecated:` header | code review | [`gaps.md`](../../future-architecture/gaps.md) J |
217
+ | NFR-MAINT-05 | Synthetic transactions per deploy | presence + success | release-pipeline | [`gaps.md`](../../future-architecture/gaps.md) I |
218
+ | NFR-MAINT-06 | Backward-compat L4↔L1 | N-2 floor; cross-version capability negotiation tested | matrix test | [`gaps.md`](../../future-architecture/gaps.md) J.1 |
219
+ | NFR-MAINT-07 | Schema migrations forward-only, reversible per release, executed by separate Job; no runtime-ORM schema-gen | migration plan committed | release-pipeline | [`02-layer4-control-plane.md`](../../future-architecture/architecture/02-layer4-control-plane.md) §schema |
220
+ | NFR-MAINT-08 | Reproducible GitOps deployment | declarative SOT; drift-detection ≤5 min | GitOps lint + drift probe | [`gaps.md`](../../future-architecture/gaps.md) I |
221
+ | NFR-MAINT-09 | Mutation-testing score on auth / sandbox / audit / egress packages | ≥60% per release | mutation-testing report attached to release | `CLAUDE.md` CI ruleset |
222
+ | NFR-MAINT-10 | Patch coverage on changed files | ≥80% per PR | CI gate | `CLAUDE.md` CI ruleset |
223
+ | NFR-MAINT-11 | Property-based tests on every parser / scheduler / policy engine | green per release | per-release CI gate | `CLAUDE.md` CI ruleset |
224
+ | NFR-MAINT-12 | Threat-model re-runs on DFD-bearing PRs | new HIGH without ADR mitigation = block | per-PR threat-model pass | `CLAUDE.md` CI ruleset |
225
+ | NFR-MAINT-13 | External pen-test cadence | annually (baseline); "after major release" `tbd` (`arch/pentest-cadence-major-release`) | summary in TPRM-pack | industry-baseline (banking-vendor convention) |
226
+ | NFR-MAINT-AUDIT-SCHEMA | Audit-event schema = OCSF v1.x JSON primary; transformer outputs ship as CEF + Elastic ECS + Chronicle UDM; SIEM bridges (Splunk HEC, ArcSight CEF, syslog-TLS baseline; Elastic ECS, Chronicle UDM, Kafka, S3 PutObject opt-in) green per release; mandatory fields `trace_id`, `session_id`, `actor_id`, `resource`, `action`, `outcome`; OCSF schema upgrade ≤90 d after major OCSF release; N-1 backward-compat | per-release schema-conformance | OCSF JSON CI gate + bridge integration | OCSF v1.x spec (open) |
227
+
228
+ ## 7. Flexibility (Portability)
229
+
230
+ | ID | Scenario | Target | Verification | Source |
231
+ |---|---|---|---|---|
232
+ | NFR-FLEX-01 | Egress endpoints are configuration, not compiled-in — any allow-listed destination (LLM API, object store, internal API) is reachable without OCU code changes; zero upstream-vendor SDK imported in CI scan. Provider selection and the agent loop are the calling client's concern, not OCU's | endpoint added by config only; CI scan finds no vendor SDK | CI lint + integration test | DORA Art. 29 |
233
+ | NFR-FLEX-02 | Sandbox runtime ladder — `runc` and `gVisor` in v1, buildable from the same artefact; microVM tier (hardware-virt; named example: Firecracker; packaging via Kata Containers or direct is a component-spec ADR) post-v1 at [`arch/microvm-tier-v1.1`](https://github.com/Wide-Moat/open-computer-use/issues/161). Deployment selects the highest tier the host substrate supports | per-release artifact inventory; tier-portability test | release pipeline | [`04-layer2-runtimes.md`](../../future-architecture/architecture/04-layer2-runtimes.md) §tiers |
234
+ | NFR-FLEX-03 | Identity provider portability — OIDC + SCIM 2.0 + SPIFFE as the platform surface (a SAML-only or LDAP/AD customer IdP federates in through Dex or Keycloak, never an OCU SAML/LDAP surface); ≥3 commercial IdP vendors green per release; platform always the relying-party — no in-house JWT issuer / SCIM endpoint / user table with passwords. The specific vendor test matrix lands in the IdP-integration component spec | per-release integration test | CI lint + integration | NYDFS Part 500 + [`gaps.md`](../../future-architecture/gaps.md) B |
235
+ | NFR-FLEX-04 | KMS / HSM portability — PKCS#11 + KMIP; ≥2 vendors green per release; tested against AWS KMS/CloudHSM + Azure Key Vault HSM + GCP Cloud KMS/HSM + Thales Luna + Entrust nShield; absent HSM, runtime falls back to a local KMS abstraction with documented downgrade (solo / one-click path) | HSM-conformance per release; local-fallback integration test | release pipeline | NIST 800-57 + one-click invariant |
236
+ | NFR-FLEX-05 | `SkillProvider` abstraction stable; v1 ships zero default skills bundled | abstraction stable; zero bundled skills | release artifact inventory | `CLAUDE.md` v1 non-goals |
237
+ | NFR-FLEX-06 | Same egress invariant across Docker Compose + k8s + microVM (when the microVM tier ships) | one invariant, three thin wrappers | cross-substrate test | [`design-notes.md`](../../future-architecture/design-notes.md) DN-1 |
238
+ | NFR-FLEX-07a | Air-gap installer artefact — zero outbound internet during install when air-gap mode selected | offline-install test against air-gap installer image | release pipeline | primitives-backlog (air-gap) |
239
+ | NFR-FLEX-07b | Standard installer — internet egress permitted at install time; ≤5 documented run-time egress endpoints per deployment | documented endpoint list per release; one-click solo install preserves Compose path | release pipeline + Compose smoke test | one-click invariant + [`gaps.md`](../../future-architecture/gaps.md) H |
240
+ | NFR-FLEX-08 | `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` + custom CA bundle injection per component | integration test | release pipeline | [`gaps.md`](../../future-architecture/gaps.md) H |
241
+ | NFR-FLEX-09 | Substrate independence — identical sandbox image runs on ≥3 substrates; CI matrix passes on Docker Compose AND target k8s per release | matrix green | cross-substrate CI matrix | [`01-layers.md`](../../future-architecture/architecture/01-layers.md) §substrate independence |
242
+ | NFR-FLEX-10 | Decoupled Control plane vs Compute plane — orchestrator does not depend on runtime details; guest builds itself given network + credentials | architecture audit | release review | [`01-layers.md`](../../future-architecture/architecture/01-layers.md) §control vs compute |
243
+ | NFR-FLEX-11 | Image tier portability (slim → max; arbitrary OCI; flexible limits; optional GPU passthrough) | tiers buildable from same Dockerfile pipeline | release inventory | [`09-templates.md`](../../future-architecture/architecture/09-templates.md) §tiers |
244
+ | NFR-FLEX-12 | Customer-tenant Compute plane as first-class deployment shape — Control plane carries metadata only; Compute plane (compute + storage + logs) runs in customer tenant | customer-hosted Compute plane option green per release | per-release integration | primitives-backlog (customer-tenant Compute plane) |
245
+ | NFR-FLEX-13 | k8s-distro portability — Helm chart on any conformant k8s ≥1.28 without flavor glue; CI matrix tests kind + EKS + RKE2 per release | CI matrix | release pipeline | future ADR (`arch/adr-k8s-distros`) |
246
+ | NFR-FLEX-14 | MCP is OCU's inbound wire protocol — the Control plane is an MCP server to the calling client (which runs the loop) and an MCP client to customer skill packs; no upstream-vendor SDK hard-coded | protocol-compliance test green | release pipeline | [`02-layer4-control-plane.md`](../../future-architecture/architecture/02-layer4-control-plane.md) §MCP gateway |
247
+ | NFR-FLEX-15 | Egress posture follows need, a ladder not a fixed default (ADR-0007): deny-all (no outbound need) · transparent pass-through (unauthenticated internet, no CA) · egress-wide bump (an upstream credential is configured — the default at this rung; per-deployment CA auto-generated and its public cert auto-injected into the sandbox trust store at start) · external SDS source (enterprise lifecycle off-box). Bump is the default only when an upstream credential is configured, never imposed on a deployment that needs none, so the one-click solo path holds at every rung. DLP-ICAP (NFR-COMP-28) is a configuration of the bump rung, not a separate rung. The CA-trust-store invariant applies only at the bump rung and above | per-rung integration test (deny-all blocks; transparent reaches an unauth endpoint with no CA; bump auto-injects CA and attaches the credential) | release pipeline | [`../02-trust-boundaries.md`](../02-trust-boundaries.md) §7 + [ADR-0007](../adr/0007-egress-auth-mechanism.md) + one-click invariant |
248
+
249
+ ## 8. Compliance
250
+
251
+ | ID | Scenario | Target | Verification | Source |
252
+ |---|---|---|---|---|
253
+ | NFR-COMP-01 | Audit-log retention — 7 y default / 10 y configurable, two-tier hot (≤90 d) → cold, machine-enforced by the Audit-pipeline retention policy on both shelves. The cold tier is realized as WORM (S3 Object Lock Compliance or equivalent) on the full shelf; on the minimal shelf the retention floor holds on a plain file system with tamper-evidence supplied by the hash-chain + signed Merkle head (NFR-SEC-03) — tamper-evident (deletion detectable via the chain and the transparency-log head), not WORM-immutable. The retention floor is mandatory on both shelves; only the WORM substrate is shelf-conditional | retention-policy audit on both shelves; WORM object-lock check when the full-shelf cold tier is wired | per-release | FCA SYSC 9 / FINRA / MAS overlay + EU AI Act Art. 19(1) floor |
254
+ | NFR-COMP-02 | DORA Register of Information — 7 fields per third-party ICT provider populated for every BoM row | BoM linter | per-release | DORA Art. 28 + RTS-2025/532 |
255
+ | NFR-COMP-03 | EU AI Act Annex III conformity checklist per release; release blocks if controls absent; Art. 12/13/14/15/17/19/49 each mapped | pass/fail | release-pipeline | EU AI Act Art. 12 + 15 + 72 + Annex III §5(b) |
256
+ | NFR-COMP-04 | DORA major-incident classification candidate emission — platform telemetry enables customer to meet timeline (classification is customer-side) | telemetry available ≤1 h post-event; bundle supports initial ≤4 h after classification (≤24 h after detection), intermediate ≤72 h, final ≤1 month | incident-drill | DORA-RTS-2025/301 Art. 5 verbatim |
257
+ | NFR-COMP-05 | NYDFS § 500.17 cybersecurity-event notification telemetry | ≤72 h notification supported; ransomware-payment ≤24 h | incident-drill | NYDFS § 500.17(a) + (c) |
258
+ | NFR-COMP-06 | NYDFS contractual-clause completeness — 8 clauses populated incl. AI-acceptable-use + training-data | template review per release | per-release | NYDFS Industry Letter 21 Oct 2025 |
259
+ | NFR-COMP-07 | Evidence-as-code bundle per release — immutable + attached; ≤7 d to TPRM intake; includes the latest available SOC 2 attestation (Type I from GA, Type II from GA+12 months), SIG Lite + Core, CAIQ v4, CSA STAR L2, ISO 27001 cert, pen-test exec summary, DORA RoI template row, CycloneDX SBOM, SLSA L3 provenance, VEX. SOC 2 and ISO 27001 evidence claims require HSM-rooted key custody (NFR-FLEX-04) and audit-pipeline mandatory delivery (NFR-MAINT-AUDIT-SCHEMA); deployments without HSM-rooted custody carry the bundle but do not carry the attestation claim | bundle present per release; field-level completeness gate | release-pipeline | primitives-backlog (evidence-as-code) |
260
+ | NFR-COMP-08 | Sub-processor disclosure — public list + 30-day change notification + machine-readable Atom/JSON changelog + DPA addendum mechanism; chain depth ≥3 | BoM audit + feed-consumption test | per-release | NYDFS Industry Letter + DORA-RTS-2025/532 |
261
+ | NFR-COMP-09 | **[REVISIT — non-gating]** Post-market monitoring data flow (EU AI Act Art. 72) — per-release plan + telemetry collectable | release notes | per-release | EU AI Act Art. 72 |
262
+ | NFR-COMP-10 | **[REVISIT — non-gating]** DPIA / FRIA refresh per major release + on substantial change | template review | per-release | GDPR Art. 35 + EU AI Act Art. 26 |
263
+ | NFR-COMP-11 | Tenant-scoped audit isolation | per-tenant query returns 0 rows for other tenants | integration test | [`gaps.md`](../../future-architecture/gaps.md) A |
264
+ | NFR-COMP-12 | GDPR Art. 17 right-to-be-forgotten — audit-log tombstoning mechanism present; completion SLA `tbd` (`arch/gdpr-rtb-sla`) | end-to-end RTB test | per-release | GDPR Art. 17 + [`gaps.md`](../../future-architecture/gaps.md) C |
265
+ | NFR-COMP-13 | Data residency — zero cross-region traffic for tagged tenant; per-region pinning explicit for compute + storage + logs | network-policy audit | per-release | [`gaps.md`](../../future-architecture/gaps.md) C |
266
+ | NFR-COMP-14 | **[REVISIT — non-gating]** EU AI Act Art. 15 accuracy declaration (qualitative) — every model deployment publishes accuracy metric + methodology | release notes | per-release | EU AI Act Art. 15(1) + 15(3) verbatim |
267
+ | NFR-COMP-15 | SR 26-2 carve-out — platform governance hooks provide customer's parallel-framework evidence for agentic AI. The SR 26-2 evidence pack is available when HSM-rooted key custody (NFR-FLEX-04) is wired and the Merkle-head submission envelope is hardware-signed per NFR-SEC-03; deployments without that custody carry the underlying telemetry but not the attestation claim | per-release evidence bundle includes logging + accountability + escalation | TPRM-pack audit | SR 26-2 verbatim |
268
+ | NFR-COMP-16 | Incorporated code permissive-licensed only (Apache / MIT / BSD / MPL); AGPL/SSPL/BUSL not in bundled artefacts; AGPL components (Loki/Tempo/Grafana) only as separate services, never linked | dep-graph audit | license scanner | future ADR (`arch/adr-licence-allowlist`) |
269
+ | NFR-COMP-17 | Per-component `compliance:` front-matter — declares SOC 2 / ISO / DORA controls satisfied; `controls-matrix.md` auto-generated | YAML field populated; CI fails on stale matrix | CI gate | `CLAUDE.md` doc-discipline |
270
+ | NFR-COMP-18 | **[REVISIT — non-gating]** ISO/IEC 42001:2023 AI Management System conformance | scope statement + cert in evidence bundle | per-release | ISO/IEC 42001:2023 |
271
+ | NFR-COMP-19 | Public Vulnerability Disclosure Program landing page (`security.txt` + PGP-signed contact) AND bug bounty | VDP page live + bounty live before GA | per-release | industry-baseline (TPRM checklist) |
272
+ | NFR-COMP-20 | Per-component status page — minimum 4 named components (Control plane, Compute plane runtime, Egress trust-edge, Audit pipeline) with independent uptime ≥90 d + Atom/RSS subscription + email/webhook channels minimum | live per component | per-release | industry-baseline (Atlassian Statuspage convention) |
273
+ | NFR-COMP-21 | DORA Art. 30 right-to-audit — audit-rights template clause + 12-month exit-assistance runbook | per release | template + runbook present | DORA Art. 30 |
274
+ | NFR-COMP-22 | EU Cyber Resilience Act 2024/2847 baseline — SBOM mandate + 24 h vulnerability disclosure workflow; obligations active from 11 Dec 2027; pilot evidence collected per release from 2026-12 onward | signed SBOM + workflow integration-tested | per-release | EU CRA Reg 2024/2847 |
275
+ | NFR-COMP-23 | TLPT participation supported for TIBER-scope customers (artefacts + access mode); cadence customer-led, not platform-mandated | TLPT-access mode documented | per-release | DORA Art. 26-27 |
276
+ | NFR-COMP-24 | NIS2 Art. 23 incident-reporting cascade — 24 h early-warning + 72 h notification telemetry hook | incident-drill | per-release | NIS2 Directive Art. 23 |
277
+ | NFR-COMP-25 | **[REVISIT — non-gating]** ZDR contractual-clause checklist per supported managed LLM upstream | presence-gate per release | CI gate | per-upstream ZDR docs (cited at release) |
278
+ | NFR-COMP-26 | **[REVISIT — non-gating]** Configurable prompt-redaction filter before any external LLM call; per-tenant policy; redaction events audited | release pipeline | integration test | NYDFS Industry Letter (training-data clause) |
279
+ | NFR-COMP-27 | SOAR bidirectional — signed webhook OUT (event payloads `session.flagged`, `policy.violation`, `dlp.hit`, `auth.anomaly`); admin API IN (quarantine session / revoke token) | versioned + integration-tested per release | release pipeline | NIST 800-61 + industry SOAR convention |
280
+ | NFR-COMP-28 | DLP at egress — ICAP hook + outbound classifier (rule-based or LLM-based) + block-or-redact policy per tenant; HTTP-classifier for outbound prompt-leak detection | per-release pass/fail | integration test | primitives-backlog (egress DLP) |
281
+ | NFR-COMP-29 | PAM — just-in-time admin elevation via OIDC-asserted claims on the full shelf (integration with the customer's PAM tool; a SAML-only PAM federates in through Dex or Keycloak); host-rooted local operator credential on the minimal shelf where no IdP is wired; no shared service accounts in production on either shelf | per-release audit | integration test | NIST 800-53 AC-2(7) |
282
+ | NFR-COMP-30 | FSL-1.1 procurement-redline pack ships per release — DPA template + SCCs + FSL-1.1 commentary explaining 2-year Apache-2.0 conversion mechanic + competing-SaaS clause | pack in evidence bundle | per-release | tracked: `arch/fsl-redline-pack` |
283
+
284
+ ## 9. Cost
285
+
286
+ | ID | Scenario | Target | Verification | Source |
287
+ |---|---|---|---|---|
288
+ | NFR-COST-01 | Cost per concurrent session at p50 load | `tbd` (`arch/cost-per-session-baseline`) | pilot telemetry | open (no peer baseline) |
289
+ | NFR-COST-02 | Egress-edge overhead cap — added latency over a direct egress call to any allow-listed endpoint | ≤10% over a direct call (`tbd` finalisation `arch/egress-overhead-cap`) | internal economics | industry shape |
290
+ | NFR-COST-03 | Audit-pipeline cost at scale | `tbd` (`arch/audit-cost-per-tb-year`) | internal economics | open (no peer baseline) |
291
+ | NFR-COST-04 | Control-plane fixed cost (no traffic) | `tbd` (`arch/control-plane-idle-cost`) | pilot telemetry | open (no peer baseline) |
292
+ | NFR-COST-05 | Per-session billing primitives emitted | CPU-min, RAM-GB-min, storage-GB-day (in-session mounted footprint, not retained-byte-days), egress bytes, MCP-call count | metric-schema audit | [`gaps.md`](../../future-architecture/gaps.md) E |
293
+ | NFR-COST-06 | Per-tenant aggregate quotas — concurrent sessions, MCP calls/min, storage GB, egress bytes/day | quota integration test | release pipeline | [`gaps.md`](../../future-architecture/gaps.md) A |
294
+ | NFR-COST-07 | Orphan-cleanup ceilings (Tier 3, not audit; backstop GC, not a retention guarantee — the workspace is scrubbed at teardown per NFR-SEC-65/54) — container ≤24 h, volume ≤7 d, scratch ≤7 d: upper bounds after which abandoned in-session residue is force-deleted | configuration audit | per-release | `cron/cleanup.sh` |
295
+ | NFR-COST-08 | Real-time tenant-aggregate cost emission + period rollup at hour / day / month | metric-schema audit | per-release | [`gaps.md`](../../future-architecture/gaps.md) E.2 |
296
+
297
+ ## Anti-pattern rows (forbidden by named NFRs above)
298
+
299
+ Each anti-pattern is forbidden by ≥1 row above.
300
+
301
+ - AP-1 — trusting in-VM memory as a secret store (`/proc/N/mem` readable by in-VM root). Forbidden by NFR-SEC-23, NFR-SEC-29, NFR-SEC-32.
302
+ - AP-2 — exposing `docker.sock` to guests. Forbidden by NFR-SEC-14.
303
+ - AP-3 — allow-list by hostname only, not by resolved IP + SNI at connect time. Forbidden by NFR-SEC-12, NFR-SEC-17.
304
+ - AP-4 — symmetric HS256 signing key without rotation, no `kid`. Forbidden by NFR-SEC-11.
305
+ - AP-5 — JWT accepted without verification in production. Forbidden by NFR-SEC-09.
306
+ - AP-6 — PVC for sandbox session workspace. Forbidden by NFR-SEC-31 (filesystem-prefix isolation makes cross-session reuse architecturally impossible) + NFR-SEC-13 (per-session KMS key destroyed on session end); cleanup defaults in NFR-COST-07 supporting.
307
+ - AP-7 — `--seccomp false` / `--seccomp log` in production. Forbidden by NFR-SEC-02, NFR-SEC-14.
308
+ - AP-8 — VNC for AI-action loops. Forbidden by NFR-IC-03 + NFR-PERF-05 (CDP screencast).
309
+ - AP-9 — weakened-isolation flags in production. Forbidden by NFR-SEC-02, NFR-SEC-05.
310
+ - AP-10 — service-per-session in k8s. Forbidden by NFR-PERF-12.
311
+ - AP-11 — single global agent binary without per-template version pinning. Forbidden by NFR-MAINT-06.
312
+ - AP-12 — kernel below the supported floor. Forbidden by NFR-SEC-35 + NFR-MAINT-01 (CVE-patch SLA).
313
+ - AP-13 — picking the sandbox tier by data classification (e.g. "NPI → microVM" or "PUBLIC → runc"). The container-escape attack surface for adversarial LLM-issued code is identical regardless of data class. Data class governs audit-record retention (NFR-COMP-01), key custody (NFR-SEC-33), and residency (NFR-COMP-13); the workload-trust profile picks the tier. Forbidden by NFR-SEC-02 + NFR-SEC-38.
314
+
315
+ ## Long-form scenarios
316
+
317
+ Eight scenarios are candidates for full Source / Stimulus / Response / Response-Measure treatment in a follow-up PR: NFR-SEC-01 (kill switch), NFR-SEC-06 (replay bundle), NFR-REL-01..03 (RTO/RPO trio), NFR-SEC-04 (BYOK rotation), NFR-SEC-08 (egress allow-list), NFR-MAINT-AUDIT-SCHEMA (OCSF), NFR-SEC-26 (internal service-to-service auth), NFR-FLEX-12 (customer-tenant Compute plane). Tracked: `arch/long-form-nfr-scenarios`.
318
+
319
+ ## Open questions
320
+
321
+ 1. NFR ID versioning policy on breaking changes — major-version-bump vs supersede. Track: `arch/nfr-versioning-policy`.
322
+ 2. NFR-violation surface — release notes + dashboard + both? Track: `arch/nfr-violation-reporting`.
323
+ 3. SLO vs hard-threshold framing — error-budget rows vs binary pass/fail. Track: `arch/nfr-slo-vs-threshold`.
324
+ 4. Pause-pod overprovisioning ratio per node pool. Track: `arch/pause-pod-overprovisioning-ratio`.
325
+ 5. Substrate-specific TLS enforcement choice (k8s service-mesh vs Compose-network vs microVM-vsock — microVM tier post-v1, [`arch/microvm-tier-v1.1`](https://github.com/Wide-Moat/open-computer-use/issues/161)) — component-spec level decision. Track: `arch/intra-platform-tls-substrate-choice`.
@@ -0,0 +1,35 @@
1
+ <!-- SPDX-License-Identifier: FSL-1.1-Apache-2.0 -->
2
+ <!-- Copyright (c) 2025 Open Computer Use Contributors -->
3
+
4
+ ---
5
+ status: draft
6
+ last-reviewed: 2026-06-05
7
+ owner: "@Wide-Moat/architects"
8
+ applies-to: next/v1
9
+ ---
10
+
11
+ Principles every architectural decision must respect. Audience: reviewers and architects deciding whether a proposal fits the platform.
12
+
13
+ ## Non-negotiable principles
14
+
15
+ **We build the control plane and the sandbox runtime; everything else we integrate.** Those two are OCU's accountable surface — what no mature market product provides — so every neighbouring capability is integrated off-the-shelf or customer-provided over a published contract, and a dependency is bundled only when it is part of that core ([02-nfrs.md](02-nfrs.md) §Scope ownership; [05-licensing-posture.md](05-licensing-posture.md) §Bundled vs not-bundled). Anti-example: shipping a bundled audit bus and owning its CVE, SBOM, and version lifecycle when the customer already runs Kafka.
16
+
17
+ **Agent loop stays outside OCU.** The loop — model query, response handling, reflection — runs in the calling client, never in OCU. Anti-example: OCU as an LLM proxy that selects the model and runs the tool-execution loop internally.
18
+
19
+ **Model agnostic by construction.** OCU does not host, select, or provision LLMs; the model choice is the caller's. A sandbox tool that needs an LLM reaches it as one allow-listed egress endpoint, governed by the Egress trust-edge like any other upstream. Anti-example: a default bundled model or a model-selection API.
20
+
21
+ **Guest holds no long-lived upstream secret.** The sandbox never holds a credential that reaches a backend outside OCU (storage, SDS, KMS, LLM); a session-scoped handle is acceptable, the upstream key stays host-side and injects at the trust-edge only ([NFR-SEC-23](02-nfrs.md), [ADR-0007](../adr/0007-egress-auth-mechanism.md)). Anti-example: the guest receiving an object-store access key or a hardcoded API token.
22
+
23
+ **Kill-switch and lifecycle mutation are unreachable from the agent path.** Session revoke, quota kill, and denylist mutation have no network route from the path that carries tool-call execution; the non-reachability is a network-policy invariant ([NFR-SEC-52](02-nfrs.md)), not an in-process route guard. The revoke itself enforces as an in-process denylist check on every Compute-plane RPC ([02-trust-boundaries.md](../02-trust-boundaries.md) §7), propagated platform-wide within ≤5 min ([NFR-SEC-04](02-nfrs.md)). Anti-example: an agent-callable RPC that revokes its own session.
24
+
25
+ **One-click solo install holds at every rung.** The minimal shelf — single operator, self-signed CA, file-system audit, `runc` — runs from one `docker-compose up` with no external service, no cloud credential, and no pre-staged key ([NFR-FLEX-15](02-nfrs.md)). Opt-in compliance machinery layers on top; it never becomes a prerequisite for the first session. Anti-example: requiring IdP enrollment or external-vault integration before a session can run.
26
+
27
+ **Audit events are immutable and hash-linked.** The OCSF event stream is written once, never modified, and hash-chained so tampering is detectable ([NFR-SEC-03](02-nfrs.md)); the audit-write is on the critical path of a privileged action, fail-closed. Anti-example: audit in a mutable store with no hash chain.
28
+
29
+ **Compliance evidence ships with every release.** Each release carries its attestations as build artifacts — signed SBOM, SLSA provenance, threat-model traces, control mappings — not a sales document assembled on demand. Anti-example: evidence generated retroactively under audit pressure.
30
+
31
+ **Skill registry is deferred, not invented now.** v1 ships zero bundled default skills; the `SkillProvider` abstraction stays `status: tbd` and skills load from a customer-provided registry over a stable contract ([04-non-goals.md](04-non-goals.md)). Anti-example: shipping a half-baked built-in skill format in v1 that locks customers in.
32
+
33
+ **No hosted SaaS from us.** FSL-1.1-Apache-2.0 forbids offering OCU on a hosted or embedded basis that competes with a paid version, until the per-release Apache-2.0 conversion ([05-licensing-posture.md](05-licensing-posture.md)). We ship self-hostable software. Anti-example: a managed OCU cloud service.
34
+
35
+ **The wire surface is versioned and changes additively.** The Control-plane RPC and the OCSF Published Language are versioned; a breaking change needs a major version and a deprecation window, CI-enforced ([NFR-IC-04](02-nfrs.md), [08-contracts.md](../08-contracts.md) §4). The MCP edge is a Conformist to the MCP spec and versions by date-revision negotiation, not semver. Anti-example: silently changing the operator REST response shape between releases.