@atmem/architect 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/CONSTITUTION.md +144 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +6 -0
  4. package/README.md +31 -2
  5. package/agent-skills/discovery/SKILL.md +48 -0
  6. package/agent-skills/discovery/topics.json +139 -0
  7. package/agent-skills/generation-capabilities.json +760 -0
  8. package/agent-skills/service-lifecycle.json +21 -0
  9. package/agent-skills/specialists/architecture/SKILL.md +15 -0
  10. package/agent-skills/specialists/aws/SKILL.md +17 -0
  11. package/agent-skills/specialists/azure/SKILL.md +7 -0
  12. package/agent-skills/specialists/composition/SKILL.md +17 -0
  13. package/agent-skills/specialists/devops/SKILL.md +10 -0
  14. package/agent-skills/specialists/finops/SKILL.md +7 -0
  15. package/agent-skills/specialists/gcp/SKILL.md +7 -0
  16. package/agent-skills/specialists/ibm/SKILL.md +7 -0
  17. package/agent-skills/specialists/manifest.json +13 -0
  18. package/agent-skills/specialists/pulumi/SKILL.md +7 -0
  19. package/agent-skills/specialists/security/SKILL.md +7 -0
  20. package/agent-skills/specialists/terraform/SKILL.md +14 -0
  21. package/agent-skills/upstream/aws/LICENSE +175 -0
  22. package/agent-skills/upstream/aws/SKILL.md +125 -0
  23. package/agent-skills/upstream/azure/LICENSE +21 -0
  24. package/agent-skills/upstream/azure/SKILL.md +387 -0
  25. package/agent-skills/upstream/gcp/LICENSE +202 -0
  26. package/agent-skills/upstream/gcp/SKILL.md +159 -0
  27. package/agent-skills/upstream/manifest.json +57 -0
  28. package/agent-skills/upstream/pulumi/LICENSE +201 -0
  29. package/agent-skills/upstream/pulumi/SKILL.md +501 -0
  30. package/agent-skills/upstream/terraform/LICENSE +373 -0
  31. package/agent-skills/upstream/terraform/SKILL.md +316 -0
  32. package/agent-skills/workflows/workflows.json +601 -0
  33. package/cli/architect.mjs +3 -0
  34. package/cli/runtime.mjs +115 -0
  35. package/dist/assets/html2canvas.esm-QH1iLAAe.js +22 -0
  36. package/dist/assets/index-BTLHaa3J.css +1 -0
  37. package/dist/assets/index-CQ2C1gKF.js +21338 -0
  38. package/dist/assets/index.es-DTyqIdaO.js +18 -0
  39. package/dist/assets/purify.es-CAi2OJFm.js +3 -0
  40. package/dist/assets/visual-export-Ox0j5xj5.js +173 -0
  41. package/dist/favicon.svg +2 -0
  42. package/dist/fonts/DM-Sans-OFL.txt +93 -0
  43. package/dist/fonts/Manrope-OFL.txt +93 -0
  44. package/dist/fonts/NotoSans-Regular.ttf +0 -0
  45. package/dist/fonts/OFL.txt +94 -0
  46. package/dist/fonts/dm-sans-latin-wght-normal.woff2 +0 -0
  47. package/dist/fonts/manrope-latin-wght-normal.woff2 +0 -0
  48. package/dist/index.html +4 -0
  49. package/dist/licenses/atmem-APACHE-2.0.txt +202 -0
  50. package/dist/licenses/aws-architect-LICENSE.txt +17 -0
  51. package/dist/licenses/aws-mcp-LICENSE.txt +175 -0
  52. package/dist/licenses/aws-mcp-NOTICE.txt +1 -0
  53. package/dist/licenses/cloud-emulation-notices.txt +36619 -0
  54. package/dist/licenses/dependency-notices.txt +6379 -0
  55. package/dist/licenses/emulation-notices.txt +717 -0
  56. package/dist/licenses/github-copilot-sdk-LICENSE.txt +21 -0
  57. package/dist/licenses/memory-dependency-notices.txt +3319 -0
  58. package/dist/licenses/openarchflow-LICENSE.txt +21 -0
  59. package/dist/licenses/python-dependency-notices.txt +11951 -0
  60. package/docs/upstream-lock.json +26 -0
  61. package/knowledge/engineering-practices.json +536 -0
  62. package/package.json +30 -4
  63. package/packaging/uv-release-lock.json +54 -0
  64. package/public/licenses/atmem-APACHE-2.0.txt +202 -0
  65. package/public/licenses/aws-architect-LICENSE.txt +17 -0
  66. package/public/licenses/aws-mcp-LICENSE.txt +175 -0
  67. package/public/licenses/aws-mcp-NOTICE.txt +1 -0
  68. package/public/licenses/cloud-emulation-notices.txt +36619 -0
  69. package/public/licenses/dependency-notices.txt +6379 -0
  70. package/public/licenses/emulation-notices.txt +717 -0
  71. package/public/licenses/github-copilot-sdk-LICENSE.txt +21 -0
  72. package/public/licenses/memory-dependency-notices.txt +3319 -0
  73. package/public/licenses/openarchflow-LICENSE.txt +21 -0
  74. package/public/licenses/python-dependency-notices.txt +11951 -0
  75. package/scripts/terraform-render.mjs +8 -0
  76. package/server/__init__.py +0 -0
  77. package/server/abstraction.py +28 -0
  78. package/server/agent_runtime.py +153 -0
  79. package/server/app.py +257 -0
  80. package/server/architect.py +112 -0
  81. package/server/architecture_activity.py +67 -0
  82. package/server/attachments.py +101 -0
  83. package/server/cloud-emulation-requirements.txt +29 -0
  84. package/server/codex_app_server.py +219 -0
  85. package/server/codex_engineering_backend.py +266 -0
  86. package/server/codex_worker_policy.py +193 -0
  87. package/server/contracts.py +315 -0
  88. package/server/copilot_worker.py +16 -0
  89. package/server/dependency_mirror.py +54 -0
  90. package/server/design_patch.py +43 -0
  91. package/server/emulation-requirements.txt +8 -0
  92. package/server/emulation_adapters.py +20 -0
  93. package/server/emulation_routes.py +98 -0
  94. package/server/emulation_worker.py +351 -0
  95. package/server/engineering_artifacts.py +221 -0
  96. package/server/engineering_assets/application-runtime.json +4372 -0
  97. package/server/engineering_assets/architecture_work.schema.json +79 -0
  98. package/server/engineering_assets/materialize_runtime.py +62 -0
  99. package/server/engineering_assets/prepare_tools.py +96 -0
  100. package/server/engineering_assets/sql_validation.py +59 -0
  101. package/server/engineering_contexts.py +120 -0
  102. package/server/engineering_delivery.py +210 -0
  103. package/server/engineering_finalization.py +210 -0
  104. package/server/engineering_handoff.py +172 -0
  105. package/server/engineering_jobs.py +206 -0
  106. package/server/engineering_knowledge.py +75 -0
  107. package/server/engineering_reconciliation.py +159 -0
  108. package/server/engineering_routes.py +483 -0
  109. package/server/engineering_sessions.py +273 -0
  110. package/server/engineering_tools.py +166 -0
  111. package/server/generation_lint.py +18 -0
  112. package/server/local_providers.py +185 -0
  113. package/server/local_validation.py +236 -0
  114. package/server/memory-requirements.lock +181 -0
  115. package/server/memory-requirements.txt +6 -0
  116. package/server/memory_context.py +58 -0
  117. package/server/memory_routes.py +141 -0
  118. package/server/memory_service.py +306 -0
  119. package/server/memory_worker.py +129 -0
  120. package/server/openai_voice.py +80 -0
  121. package/server/orca_handoff.py +90 -0
  122. package/server/packaged_app.py +9 -0
  123. package/server/pricing.py +190 -0
  124. package/server/process_control_observation.py +31 -0
  125. package/server/prompts.py +136 -0
  126. package/server/public_faq_emulation_worker.py +44 -0
  127. package/server/requirements.lock +1618 -0
  128. package/server/requirements.txt +68 -0
  129. package/server/runtime_dependency_locks.py +27 -0
  130. package/server/runtime_evidence.py +93 -0
  131. package/server/settings.py +14 -0
  132. package/server/skills.py +103 -0
  133. package/server/storage_emulation_worker.py +160 -0
  134. package/server/structured_emulation_worker.py +48 -0
  135. package/server/terraform_routes.py +118 -0
  136. package/server/upstream/__init__.py +0 -0
  137. package/server/upstream/agent/__init__.py +1 -0
  138. package/server/upstream/agent/aws_architect.py +600 -0
  139. package/server/upstream/agent/config/__init__.py +1 -0
  140. package/server/upstream/agent/config/agent_config.py +82 -0
  141. package/server/upstream/agent/config/prompts.py +138 -0
  142. package/server/upstream/agent/rate_limiter.py +62 -0
  143. package/server/upstream/utils/__init__.py +1 -0
  144. package/server/upstream/utils/file_writer.py +43 -0
  145. package/server/validation_applicability.py +85 -0
  146. package/server/validation_jobs.py +252 -0
  147. package/server/validation_workers.py +48 -0
  148. package/server/voice_routes.py +91 -0
  149. package/server/voice_worker.py +26 -0
  150. package/server/windows_snapshot.py +119 -0
  151. package/specs/028-convergence-evaluation/evidence/20261110-ibm-invoice-native/registry-structured/qualification.json +72 -0
  152. package/specs/028-convergence-evaluation/evidence/20261110-invoice-runtime/durable-current/receipt.json +61 -0
  153. package/specs/029-general-purpose-engine/evidence/20261111-runtime-dependencies/sdk/receipt.json +22 -0
  154. package/src/ArchitectureActivity.jsx +54 -0
  155. package/src/ArchitectureWorkPanel.jsx +39 -0
  156. package/src/ArtifactChecks.jsx +49 -0
  157. package/src/BlockRequirements.jsx +13 -0
  158. package/src/BrainActivity.jsx +11 -0
  159. package/src/ChatMessage.jsx +29 -0
  160. package/src/ChatResizeHandle.jsx +6 -0
  161. package/src/CodePreview.jsx +8 -0
  162. package/src/ComponentReview.jsx +31 -0
  163. package/src/DeliveryViews.jsx +59 -0
  164. package/src/EmulationPanel.jsx +44 -0
  165. package/src/EngagementViews.jsx +387 -0
  166. package/src/EngineeringPanel.jsx +151 -0
  167. package/src/FileTree.jsx +7 -0
  168. package/src/FinalChecklist.jsx +15 -0
  169. package/src/HelpNote.jsx +3 -0
  170. package/src/ImplementationDelivery.jsx +91 -0
  171. package/src/JourneyViews.jsx +403 -0
  172. package/src/LocationChoices.jsx +12 -0
  173. package/src/MemoryPanel.jsx +58 -0
  174. package/src/OpenAIVoicePanel.jsx +66 -0
  175. package/src/OutputsView.jsx +71 -0
  176. package/src/ProjectChecks.jsx +44 -0
  177. package/src/TerraformView.jsx +57 -0
  178. package/src/WorkbenchDialogs.jsx +532 -0
  179. package/src/activity-presentation.mjs +28 -0
  180. package/src/ai-qualification-scenarios.mjs +31 -0
  181. package/src/approval-application-files.mjs +32 -0
  182. package/src/approval-applications.mjs +82 -0
  183. package/src/approval-spec-kit.mjs +30 -0
  184. package/src/architecture-activity.css +28 -0
  185. package/src/architecture-activity.mjs +63 -0
  186. package/src/architecture-work.mjs +176 -0
  187. package/src/artifact-work.mjs +103 -0
  188. package/src/async-documents.mjs +191 -0
  189. package/src/atflow.css +1140 -0
  190. package/src/atforma.css +748 -0
  191. package/src/atmem-tokens.css +79 -0
  192. package/src/aws-preflight.mjs +60 -0
  193. package/src/aws-public-faq.mjs +102 -0
  194. package/src/aws-validation-scenarios.mjs +10 -0
  195. package/src/aws-validation.mjs +48 -0
  196. package/src/azure-plan-mocks.mjs +25 -0
  197. package/src/azure-structured.mjs +133 -0
  198. package/src/bedrock-summary.mjs +152 -0
  199. package/src/bounded-rag.mjs +60 -0
  200. package/src/brand.css +9 -0
  201. package/src/canvas-view.mjs +28 -0
  202. package/src/capability-composition.mjs +44 -0
  203. package/src/chat-attachments.mjs +13 -0
  204. package/src/cloud-provider-locks.mjs +9 -0
  205. package/src/cloud-storage-scenarios.mjs +2 -0
  206. package/src/component-review.mjs +55 -0
  207. package/src/composition-spec-kit.mjs +30 -0
  208. package/src/consultation-context.mjs +15 -0
  209. package/src/consultation.mjs +52 -0
  210. package/src/container-contracts.mjs +5 -0
  211. package/src/container-inspection.mjs +75 -0
  212. package/src/container-runtime.mjs +30 -0
  213. package/src/container-security-inspection.mjs +49 -0
  214. package/src/container-terraform.mjs +109 -0
  215. package/src/conversation.mjs +18 -0
  216. package/src/core.mjs +863 -0
  217. package/src/cross-cloud-storage.mjs +100 -0
  218. package/src/delivery-capabilities.mjs +25 -0
  219. package/src/delivery.mjs +58 -0
  220. package/src/deployment-ownership.mjs +10 -0
  221. package/src/deployment-region.mjs +11 -0
  222. package/src/derive.mjs +31 -0
  223. package/src/design-build-flow.mjs +10 -0
  224. package/src/diagram-attention.mjs +24 -0
  225. package/src/discovery.mjs +359 -0
  226. package/src/document.mjs +170 -0
  227. package/src/emulation-feedback.mjs +61 -0
  228. package/src/emulation-guidance.mjs +37 -0
  229. package/src/engagement.mjs +274 -0
  230. package/src/engineering-client.mjs +73 -0
  231. package/src/engineering-defaults.mjs +17 -0
  232. package/src/engineering.css +31 -0
  233. package/src/enterprise-application.mjs +76 -0
  234. package/src/enterprise-aws-host-infrastructure.mjs +62 -0
  235. package/src/enterprise-aws-host-tests.mjs +15 -0
  236. package/src/enterprise-aws-infrastructure-tests.mjs +38 -0
  237. package/src/enterprise-aws-infrastructure.mjs +138 -0
  238. package/src/enterprise-google-infrastructure.mjs +84 -0
  239. package/src/enterprise-google-tests.mjs +25 -0
  240. package/src/estimate.mjs +190 -0
  241. package/src/existing-references.mjs +18 -0
  242. package/src/external-identities.mjs +17 -0
  243. package/src/faq-lambda-build.mjs +28 -0
  244. package/src/final-package.mjs +34 -0
  245. package/src/gcp-structured.mjs +104 -0
  246. package/src/generation-provider.mjs +7 -0
  247. package/src/generation-quality.mjs +69 -0
  248. package/src/handoff.mjs +141 -0
  249. package/src/ibm-registry.mjs +12 -0
  250. package/src/ibm-structured.mjs +103 -0
  251. package/src/identifiers.mjs +15 -0
  252. package/src/implementation-map.mjs +14 -0
  253. package/src/implementation-outcome.mjs +8 -0
  254. package/src/incomplete-terraform.mjs +9 -0
  255. package/src/integrations.ts +137 -0
  256. package/src/interface-contracts.mjs +30 -0
  257. package/src/invoice-application.mjs +66 -0
  258. package/src/invoice-aws-operations.mjs +136 -0
  259. package/src/invoice-aws.mjs +143 -0
  260. package/src/invoice-azure-operations.mjs +147 -0
  261. package/src/invoice-azure.mjs +134 -0
  262. package/src/invoice-builder.mjs +35 -0
  263. package/src/invoice-dependencies.mjs +43 -0
  264. package/src/invoice-gcp-operations.mjs +178 -0
  265. package/src/invoice-gcp.mjs +104 -0
  266. package/src/invoice-ibm-operations.mjs +278 -0
  267. package/src/invoice-ibm.mjs +142 -0
  268. package/src/invoice-operations.mjs +143 -0
  269. package/src/invoice-plan.mjs +45 -0
  270. package/src/invoice-region.mjs +6 -0
  271. package/src/invoice-spec-kit.mjs +61 -0
  272. package/src/invoice-state.mjs +7 -0
  273. package/src/invoice-terraform.mjs +29 -0
  274. package/src/invoice-tests.mjs +122 -0
  275. package/src/journey-workspace.css +106 -0
  276. package/src/journey.mjs +97 -0
  277. package/src/levels.mjs +145 -0
  278. package/src/local-agent.mjs +184 -0
  279. package/src/main.jsx +2481 -0
  280. package/src/model-policy-preflight.mjs +34 -0
  281. package/src/openai-voice.mjs +102 -0
  282. package/src/output-bundle.mjs +13 -0
  283. package/src/ownership-inspection.mjs +28 -0
  284. package/src/pack.mjs +201 -0
  285. package/src/pricing.mjs +85 -0
  286. package/src/production-state.mjs +8 -0
  287. package/src/project-copy.mjs +10 -0
  288. package/src/project-file.mjs +160 -0
  289. package/src/project-links.mjs +3 -0
  290. package/src/protected-state.mjs +43 -0
  291. package/src/public-faq-builder.mjs +19 -0
  292. package/src/public-faq-clouds.mjs +251 -0
  293. package/src/public-faq.mjs +122 -0
  294. package/src/pulumi.mjs +123 -0
  295. package/src/python-container.mjs +25 -0
  296. package/src/python-runtime.mjs +50 -0
  297. package/src/rag-handler.mjs +43 -0
  298. package/src/rag-web-assets.mjs +52 -0
  299. package/src/rag-web.mjs +68 -0
  300. package/src/records.mjs +177 -0
  301. package/src/resources.mjs +163 -0
  302. package/src/review.mjs +252 -0
  303. package/src/runtime/EnterpriseDocument.java +89 -0
  304. package/src/runtime/approved_http_destination.py +72 -0
  305. package/src/runtime/aws-lambda-qualification-lock.json +7 -0
  306. package/src/runtime/aws-python-lock.json +82 -0
  307. package/src/runtime/aws-web-python-lock.json +887 -0
  308. package/src/runtime/aws_json_model.py +42 -0
  309. package/src/runtime/azure-python-lock.json +863 -0
  310. package/src/runtime/azure-sources.json +8 -0
  311. package/src/runtime/azure-test-lock.json +23 -0
  312. package/src/runtime/azure_acceptance.py +192 -0
  313. package/src/runtime/azure_structured.py +153 -0
  314. package/src/runtime/bounded_rag.py +126 -0
  315. package/src/runtime/catalog_admin.py +70 -0
  316. package/src/runtime/cloud-sql-proxy-lock.json +8 -0
  317. package/src/runtime/cloud-sql-proxy-security-review.json +30 -0
  318. package/src/runtime/connector_cli.py +50 -0
  319. package/src/runtime/connector_sync.py +70 -0
  320. package/src/runtime/durable-python-lock.json +247 -0
  321. package/src/runtime/durable_workflow.py +325 -0
  322. package/src/runtime/enterprise-application-manifest.json +110 -0
  323. package/src/runtime/enterprise-application-sources.json +266 -0
  324. package/src/runtime/enterprise-auth-python-lock.json +592 -0
  325. package/src/runtime/enterprise-aws-host-bootstrap-source.json +1 -0
  326. package/src/runtime/enterprise-aws-host-probe-source.json +1 -0
  327. package/src/runtime/enterprise-aws-task-template.json +235 -0
  328. package/src/runtime/enterprise-document-lock.json +18 -0
  329. package/src/runtime/enterprise-document.Dockerfile +15 -0
  330. package/src/runtime/enterprise-runtime-aws-python-lock.json +1115 -0
  331. package/src/runtime/enterprise-runtime-azure-python-lock.json +1106 -0
  332. package/src/runtime/enterprise-runtime-gcp-python-lock.json +1060 -0
  333. package/src/runtime/enterprise-runtime-ibm-python-lock.json +1096 -0
  334. package/src/runtime/enterprise-runtime-python-lock.json +1058 -0
  335. package/src/runtime/enterprise-runtime.Dockerfile +15 -0
  336. package/src/runtime/enterprise-web-app.js +1 -0
  337. package/src/runtime/enterprise-web-entry.js +105 -0
  338. package/src/runtime/enterprise-web-lock.json +29 -0
  339. package/src/runtime/enterprise-web-notices.txt +229 -0
  340. package/src/runtime/enterprise-web.css +4 -0
  341. package/src/runtime/enterprise-web.html +8 -0
  342. package/src/runtime/enterprise_audit.py +91 -0
  343. package/src/runtime/enterprise_audit_schema.sql +25 -0
  344. package/src/runtime/enterprise_auth_schema.sql +67 -0
  345. package/src/runtime/enterprise_auth_store.py +241 -0
  346. package/src/runtime/enterprise_aws_host_bootstrap.py +120 -0
  347. package/src/runtime/enterprise_aws_host_probe.py +105 -0
  348. package/src/runtime/enterprise_aws_hosts.py +136 -0
  349. package/src/runtime/enterprise_aws_jobs.py +300 -0
  350. package/src/runtime/enterprise_aws_objects.py +93 -0
  351. package/src/runtime/enterprise_aws_transfer.py +83 -0
  352. package/src/runtime/enterprise_azure_batch_api.py +128 -0
  353. package/src/runtime/enterprise_azure_host.py +599 -0
  354. package/src/runtime/enterprise_azure_jobs.py +294 -0
  355. package/src/runtime/enterprise_azure_objects.py +234 -0
  356. package/src/runtime/enterprise_azure_pool.py +161 -0
  357. package/src/runtime/enterprise_azure_transfer.py +122 -0
  358. package/src/runtime/enterprise_configuration.py +136 -0
  359. package/src/runtime/enterprise_document.py +116 -0
  360. package/src/runtime/enterprise_document_cli.py +32 -0
  361. package/src/runtime/enterprise_document_contract.py +54 -0
  362. package/src/runtime/enterprise_document_job.py +109 -0
  363. package/src/runtime/enterprise_document_jobs.py +122 -0
  364. package/src/runtime/enterprise_document_jobs_schema.sql +23 -0
  365. package/src/runtime/enterprise_extraction_cache.py +186 -0
  366. package/src/runtime/enterprise_extraction_schema.sql +17 -0
  367. package/src/runtime/enterprise_google_jobs.py +275 -0
  368. package/src/runtime/enterprise_google_transfer.py +85 -0
  369. package/src/runtime/enterprise_http.py +212 -0
  370. package/src/runtime/enterprise_identity.py +52 -0
  371. package/src/runtime/enterprise_knowledge.py +152 -0
  372. package/src/runtime/enterprise_models.py +94 -0
  373. package/src/runtime/enterprise_native.py +181 -0
  374. package/src/runtime/enterprise_oauth.py +132 -0
  375. package/src/runtime/enterprise_operator.py +160 -0
  376. package/src/runtime/enterprise_parser_service.py +136 -0
  377. package/src/runtime/enterprise_parser_transport.py +68 -0
  378. package/src/runtime/enterprise_queries.py +255 -0
  379. package/src/runtime/enterprise_queries_schema.sql +27 -0
  380. package/src/runtime/enterprise_query_service.py +111 -0
  381. package/src/runtime/enterprise_secrets.py +110 -0
  382. package/src/runtime/enterprise_sessions.py +95 -0
  383. package/src/runtime/enterprise_sources.py +260 -0
  384. package/src/runtime/enterprise_web.py +39 -0
  385. package/src/runtime/enterprise_worker.py +68 -0
  386. package/src/runtime/export_contract_acceptance.py +18 -0
  387. package/src/runtime/faq-output-contract.json +40 -0
  388. package/src/runtime/faq-web-app.js +41 -0
  389. package/src/runtime/faq-web.css +1 -0
  390. package/src/runtime/faq-web.html +6 -0
  391. package/src/runtime/gcp-sources.json +9 -0
  392. package/src/runtime/gcp_acceptance.py +110 -0
  393. package/src/runtime/gcp_structured.py +150 -0
  394. package/src/runtime/http_acceptance.py +39 -0
  395. package/src/runtime/iap-web-app.js +36 -0
  396. package/src/runtime/iap-web-source.json +1 -0
  397. package/src/runtime/ibm-python-lock.json +856 -0
  398. package/src/runtime/ibm-sources.json +9 -0
  399. package/src/runtime/ibm_acceptance.py +133 -0
  400. package/src/runtime/ibm_structured.py +113 -0
  401. package/src/runtime/invoice-azapi-provider-lock.json +7 -0
  402. package/src/runtime/invoice-ibm-provider-lock.json +7 -0
  403. package/src/runtime/invoice-parser-lock.json +1199 -0
  404. package/src/runtime/invoice-parser-python-lock.json +56 -0
  405. package/src/runtime/invoice-parser.Dockerfile +190 -0
  406. package/src/runtime/invoice-sources.json +58 -0
  407. package/src/runtime/invoice-test-sources.json +24 -0
  408. package/src/runtime/invoice-web.css +2 -0
  409. package/src/runtime/invoice-web.html +12 -0
  410. package/src/runtime/invoice-web.js +112 -0
  411. package/src/runtime/invoice_configuration.py +17 -0
  412. package/src/runtime/invoice_document.py +95 -0
  413. package/src/runtime/invoice_extraction.py +96 -0
  414. package/src/runtime/invoice_http.py +129 -0
  415. package/src/runtime/invoice_identity.py +5 -0
  416. package/src/runtime/invoice_maintenance.py +40 -0
  417. package/src/runtime/invoice_native.py +77 -0
  418. package/src/runtime/invoice_object_store.py +153 -0
  419. package/src/runtime/invoice_operations.py +108 -0
  420. package/src/runtime/invoice_operator.py +79 -0
  421. package/src/runtime/invoice_operator_core.py +39 -0
  422. package/src/runtime/invoice_operator_job.py +147 -0
  423. package/src/runtime/invoice_parser_cli.py +17 -0
  424. package/src/runtime/invoice_parser_identity.py +39 -0
  425. package/src/runtime/invoice_parser_service.py +89 -0
  426. package/src/runtime/invoice_parser_transport.py +89 -0
  427. package/src/runtime/invoice_processing.py +24 -0
  428. package/src/runtime/invoice_retention.py +16 -0
  429. package/src/runtime/invoice_runtime_secrets.py +43 -0
  430. package/src/runtime/invoice_stage.py +80 -0
  431. package/src/runtime/invoice_web.py +39 -0
  432. package/src/runtime/invoice_worker.py +50 -0
  433. package/src/runtime/lambda_faq.py +5 -0
  434. package/src/runtime/parser-requirements.lock +4 -0
  435. package/src/runtime/policy_review.py +18 -0
  436. package/src/runtime/postgres-qualification-lock.json +21 -0
  437. package/src/runtime/public-faq-sources.json +22 -0
  438. package/src/runtime/public_catalog_admin.py +122 -0
  439. package/src/runtime/public_catalog_store.py +125 -0
  440. package/src/runtime/public_faq.py +144 -0
  441. package/src/runtime/public_faq_app.py +49 -0
  442. package/src/runtime/python-container-lock.json +18 -0
  443. package/src/runtime/rag-sources.json +10 -0
  444. package/src/runtime/rag_acceptance.py +60 -0
  445. package/src/runtime/rag_aws_adapter.py +95 -0
  446. package/src/runtime/rds-ca-source.json +9 -0
  447. package/src/runtime/rds-global-ca.pem +2888 -0
  448. package/src/runtime/state-contract-check-source.json +4 -0
  449. package/src/runtime/state_contract_check.py +338 -0
  450. package/src/runtime/structured-source.json +1 -0
  451. package/src/runtime/structured-web-app.js +71 -0
  452. package/src/runtime/structured-web-source.json +1 -0
  453. package/src/runtime/structured_http.py +105 -0
  454. package/src/runtime/structured_output.py +48 -0
  455. package/src/runtime/web-python-lock.json +802 -0
  456. package/src/runtime/web_user_admin.py +44 -0
  457. package/src/runtime/workflow_application.py +62 -0
  458. package/src/runtime/workflow_bindings.py +128 -0
  459. package/src/runtime/workflow_configuration.py +40 -0
  460. package/src/runtime/workflow_connection.py +105 -0
  461. package/src/runtime/workflow_contract.py +54 -0
  462. package/src/runtime/workflow_database.py +94 -0
  463. package/src/runtime/workflow_errors.py +6 -0
  464. package/src/runtime/workflow_http.py +178 -0
  465. package/src/runtime/workflow_identity.py +69 -0
  466. package/src/runtime/workflow_payload.py +118 -0
  467. package/src/runtime/workflow_process_stage.py +88 -0
  468. package/src/runtime/workflow_profile.py +91 -0
  469. package/src/runtime/workflow_review.py +106 -0
  470. package/src/runtime/workflow_role_bootstrap.py +104 -0
  471. package/src/runtime/workflow_schema.sql +72 -0
  472. package/src/runtime/workflow_worker.py +142 -0
  473. package/src/runtime-settings.mjs +15 -0
  474. package/src/s3-access.mjs +14 -0
  475. package/src/source-contracts.mjs +17 -0
  476. package/src/spec-kit.mjs +186 -0
  477. package/src/state-custody.mjs +32 -0
  478. package/src/state-inspection.mjs +45 -0
  479. package/src/state-spec-kit.mjs +13 -0
  480. package/src/storage-tests.mjs +25 -0
  481. package/src/structured-api.mjs +133 -0
  482. package/src/structured-contract.mjs +19 -0
  483. package/src/structured-operation-policy.mjs +2 -0
  484. package/src/structured-web.mjs +17 -0
  485. package/src/style.css +1 -0
  486. package/src/system-description.mjs +26 -0
  487. package/src/terraform-admission.mjs +66 -0
  488. package/src/terraform-composition.mjs +83 -0
  489. package/src/terraform-expressions.mjs +46 -0
  490. package/src/terraform-validation-coverage.mjs +11 -0
  491. package/src/terraform.mjs +128 -0
  492. package/src/text-statistics.mjs +51 -0
  493. package/src/upstream/openarchflow/format-payload.ts +26 -0
  494. package/src/upstream/openarchflow/import/mermaid.ts +205 -0
  495. package/src/upstream/openarchflow/import/sql-ddl.ts +109 -0
  496. package/src/upstream/openarchflow/layout.ts +54 -0
  497. package/src/upstream/openarchflow/providers/aws.ts +196 -0
  498. package/src/upstream/openarchflow/providers/azure.ts +126 -0
  499. package/src/upstream/openarchflow/providers/cloudnative.ts +71 -0
  500. package/src/upstream/openarchflow/providers/generic.ts +227 -0
  501. package/src/upstream/openarchflow/providers/integration.ts +22 -0
  502. package/src/upstream/openarchflow/providers/types.ts +2 -0
  503. package/src/upstream/openarchflow/templates.ts +937 -0
  504. package/src/upstream-catalog.mjs +10 -0
  505. package/src/useChatScroll.jsx +37 -0
  506. package/src/useEmulation.jsx +36 -0
  507. package/src/useEngineeringStatus.mjs +17 -0
  508. package/src/validation-receipt.mjs +10 -0
  509. package/src/visual-export.mjs +92 -0
  510. package/src/voice-conversation.mjs +117 -0
  511. package/src/work-intake.mjs +24 -0
  512. package/src/workflow-runtime-inventory.mjs +3 -0
@@ -0,0 +1,266 @@
1
+ """Codex adapter for portable engineering sessions; no public/browser endpoint.
2
+
3
+ Workspace registrations and scope originate from the worker's trusted control plane.
4
+ The native sandbox constrains writes/network, but this adapter alone is NOT a hosted
5
+ multi-tenant isolation boundary. Hosted workers need separately qualified isolation.
6
+ """
7
+ from pathlib import Path
8
+ from .codex_app_server import CodexAppServer, ProtocolError
9
+ from .engineering_sessions import BackendEvent, EmptySessionUnavailable, RecoveredStart, SessionError
10
+
11
+
12
+ class CodexEngineeringBackend:
13
+ name='codex-app-server'
14
+
15
+ def __init__(self,workspaces,*,client_factory=CodexAppServer,instructions='',permission_profile=None,tools=None):
16
+ self.workspaces=dict(workspaces)
17
+ self.client_factory=client_factory
18
+ self.instructions=instructions
19
+ self.permission_profile=permission_profile
20
+ self.tools=tools
21
+ if permission_profile:
22
+ # The durable coordinator must refuse a legacy-policy fallback after
23
+ # restart, even though both implementations use the same model API.
24
+ self.name=f'codex-app-server:{permission_profile}'
25
+ self.clients={}
26
+
27
+ def _workspace(self,scope,workspace):
28
+ registered=self.workspaces.get((scope,workspace))
29
+ if registered is None:
30
+ raise SessionError('Workspace is not registered for this project')
31
+ root=Path(registered).resolve(strict=True)
32
+ if not root.is_dir():
33
+ raise SessionError('Registered workspace is unavailable')
34
+ return root
35
+
36
+ @staticmethod
37
+ def _policy(root):
38
+ return {'type':'workspaceWrite','writableRoots':[str(root)],'networkAccess':False,
39
+ 'excludeSlashTmp':True,'excludeTmpdirEnvVar':True}
40
+
41
+ def _verify(self,result,root,selection):
42
+ policy=result.get('sandbox',{})
43
+ if result.get('cwd')!=str(root) or result.get('model')!=selection.model or result.get('reasoningEffort')!=selection.effort:
44
+ raise SessionError('Codex did not confirm the selected workspace, model and reasoning effort')
45
+ expected_network=bool(self.permission_profile)
46
+ if result.get('approvalPolicy')!='never' or policy.get('type')!='workspaceWrite' or policy.get('networkAccess') is not expected_network:
47
+ raise SessionError('Codex did not confirm the required local execution policy')
48
+ if policy.get('excludeSlashTmp') is not True or policy.get('excludeTmpdirEnvVar') is not True or set(policy.get('writableRoots',[]))-{str(root)}:
49
+ raise SessionError('Codex returned additional writable roots or temporary directories')
50
+ if self.permission_profile:
51
+ if result.get('activePermissionProfile',{}).get('id')!=self.permission_profile or result.get('runtimeWorkspaceRoots')!=[str(root)]:
52
+ raise SessionError('Codex did not confirm the selected worker profile and sole project root')
53
+ sources=result.get('instructionSources',[])
54
+ if not isinstance(sources,list) or any(not isinstance(source,str) or not Path(source).resolve().is_relative_to(root) for source in sources):
55
+ raise SessionError('The native worker inherited instructions outside this project workspace')
56
+ handle=result.get('thread',{}).get('id')
57
+ if not isinstance(handle,str) or not handle:
58
+ raise SessionError('Codex did not confirm a thread')
59
+ return handle
60
+
61
+ def _params(self,root,selection):
62
+ return {'cwd':str(root),'model':selection.model,'approvalPolicy':'never',
63
+ **({'permissions':self.permission_profile,'config':{'model_reasoning_effort':selection.effort}}
64
+ if self.permission_profile else {'sandbox':'workspace-write','config':{
65
+ 'model_reasoning_effort':selection.effort,
66
+ 'sandbox_workspace_write.network_access':False,
67
+ 'sandbox_workspace_write.exclude_slash_tmp':True,
68
+ 'sandbox_workspace_write.exclude_tmpdir_env_var':True}}),
69
+ **({'developerInstructions':self.instructions} if self.instructions else {})}
70
+
71
+ def _owned(self,scope,handle,selection=None):
72
+ row=self.clients.get((scope,handle))
73
+ if not row or (selection is not None and row[2]!=selection):
74
+ raise SessionError('Codex session is unavailable for this project or model selection')
75
+ return row
76
+
77
+ def _bind_tools(self,client,scope,workspace,handle):
78
+ if self.tools is None:return
79
+ async def invoke(params):
80
+ self._owned(scope,handle)
81
+ if not isinstance(params,dict) or set(params)-{'threadId','turnId','callId','tool','arguments','namespace'} or params.get('threadId')!=handle or params.get('namespace') is not None:
82
+ raise SessionError('Native tool callback belongs to another thread or namespace')
83
+ return await self.tools.invoke(scope,workspace,params.get('turnId'),params.get('callId'),params.get('tool'),params.get('arguments'))
84
+ client.dynamic_tool_handler=invoke
85
+
86
+ async def create(self,scope,workspace,selection):
87
+ root=self._workspace(scope,workspace)
88
+ client=self.client_factory(root)
89
+ try:
90
+ if self.tools is not None:client.experimental=True
91
+ await client.start()
92
+ result=await client.request('thread/start',{**self._params(root,selection),
93
+ **({'dynamicTools':self.tools.specs} if self.tools is not None else {})})
94
+ handle=self._verify(result,root,selection)
95
+ if self.permission_profile:
96
+ await client.verify_worker_tools(self.permission_profile)
97
+ if (scope,handle) in self.clients:
98
+ raise SessionError('Codex returned a previously registered thread')
99
+ self.clients[scope,handle]=(client,root,selection)
100
+ self._bind_tools(client,scope,workspace,handle)
101
+ return handle
102
+ except BaseException:
103
+ await client.close();raise
104
+
105
+ async def resume(self,scope,handle,workspace,selection):
106
+ root=self._workspace(scope,workspace)
107
+ if (scope,handle) in self.clients:
108
+ row=self._owned(scope,handle,selection)
109
+ if row[1]!=root:
110
+ raise SessionError('A session cannot change its registered workspace')
111
+ client=row[0]
112
+ process=getattr(client,'process',None)
113
+ if not getattr(client,'failure',None) and (process is None or process.returncode is None):
114
+ return
115
+ # A dead cached transport cannot recover itself. Reopen the same
116
+ # persisted native thread; never start a replacement for accepted work.
117
+ self.clients.pop((scope,handle))
118
+ await client.close()
119
+ client=self.client_factory(root)
120
+ try:
121
+ if self.tools is not None:client.experimental=True
122
+ await client.start()
123
+ # App-server resume reloads runtime configuration. Reassert the exact
124
+ # project model/effort and execution policy instead of inheriting the
125
+ # worker's current defaults, then verify its acknowledgement below.
126
+ params=self._params(root,selection)
127
+ result=await client.request('thread/resume',{
128
+ **params,'threadId':handle,'excludeTurns':True})
129
+ if self._verify(result,root,selection)!=handle:
130
+ raise SessionError('Codex resumed a different thread')
131
+ if self.permission_profile:
132
+ await client.verify_worker_tools(self.permission_profile)
133
+ self.clients[scope,handle]=(client,root,selection)
134
+ self._bind_tools(client,scope,workspace,handle)
135
+ except ProtocolError as error:
136
+ await client.close()
137
+ if error.category=='missing_thread':
138
+ raise EmptySessionUnavailable('Native thread has no stored history') from None
139
+ raise
140
+ except BaseException:
141
+ await client.close();raise
142
+
143
+ async def start(self,scope,handle,text,selection,*,request_id=None,context=None):
144
+ client,root,_=self._owned(scope,handle,selection)
145
+ inputs = self._inputs(scope, text, context)
146
+ result=await client.request('turn/start',{'threadId':handle,
147
+ 'input':inputs,'cwd':str(root),
148
+ 'model':selection.model,'effort':selection.effort,
149
+ 'approvalPolicy':'never',
150
+ **({'permissions':self.permission_profile} if self.permission_profile else {'sandboxPolicy':self._policy(root)}),
151
+ **({'clientUserMessageId':request_id} if request_id is not None else {})})
152
+ turn=result.get('turn',{})
153
+ if turn.get('status')!='inProgress' or not isinstance(turn.get('id'),str) or not turn['id']:
154
+ raise SessionError('Codex did not confirm an active engineering turn')
155
+ return turn['id']
156
+
157
+ async def recover_start(self,scope,handle,request_id):
158
+ """Match durable client message identity; never infer acceptance from text.
159
+
160
+ This is acknowledgement recovery, not an idempotent resubmission promise.
161
+ An absent/ambiguous match leaves the reservation unresolved.
162
+ """
163
+ client,_,_=self._owned(scope,handle)
164
+ cursor=None;seen=set();matches=[]
165
+ for _ in range(20):
166
+ params={'threadId':handle,'limit':100,'sortDirection':'desc','itemsView':'summary'}
167
+ if cursor is not None:params['cursor']=cursor
168
+ result=await client.request('thread/turns/list',params)
169
+ turns=result.get('data')
170
+ if not isinstance(turns,list):raise SessionError('Native start history is unavailable')
171
+ for candidate in turns:
172
+ if not isinstance(candidate,dict) or not isinstance(candidate.get('items'),list):
173
+ raise SessionError('Native start history is malformed')
174
+ for item in candidate['items']:
175
+ if not isinstance(item,dict):raise SessionError('Native message identity is malformed')
176
+ if item.get('type')=='userMessage' and item.get('clientId')==request_id:
177
+ status=candidate.get('status')
178
+ matches.append(RecoveredStart(request_id,candidate.get('id'),'running' if status=='inProgress' else status))
179
+ cursor=result.get('nextCursor')
180
+ if cursor is None:
181
+ if len(matches)>1:raise SessionError('Native start identity is ambiguous; no work was replayed')
182
+ return matches[0] if matches else None
183
+ if not isinstance(cursor,str) or not cursor or cursor in seen:
184
+ raise SessionError('Native start history cursor is invalid')
185
+ seen.add(cursor)
186
+ raise SessionError('Native start history exceeded the recovery bound')
187
+
188
+ async def observe(self,scope,handle,turn):
189
+ """Recover terminal state without resubmitting work or loading its content.
190
+
191
+ Missing, malformed or excessively paginated history is uncertain, never
192
+ an idle session. The control-plane reservation remains in place.
193
+ """
194
+ client,_,_=self._owned(scope,handle)
195
+ cursor=None
196
+ seen=set()
197
+ for _ in range(20):
198
+ params={'threadId':handle,'limit':100,'sortDirection':'desc','itemsView':'notLoaded'}
199
+ if cursor is not None:
200
+ params['cursor']=cursor
201
+ result=await client.request('thread/turns/list',params)
202
+ turns=result.get('data')
203
+ if not isinstance(turns,list):
204
+ raise SessionError('Codex turn history is unavailable; recovery is required')
205
+ for candidate in turns:
206
+ if not isinstance(candidate,dict):
207
+ raise SessionError('Codex returned malformed turn history')
208
+ if candidate.get('id')==turn:
209
+ status=candidate.get('status')
210
+ if status=='inProgress':
211
+ return None
212
+ if status in {'completed','failed','interrupted'}:
213
+ return BackendEvent(turn,status)
214
+ raise SessionError('Codex returned an unknown recovered turn status')
215
+ cursor=result.get('nextCursor')
216
+ if cursor is None:
217
+ break
218
+ if not isinstance(cursor,str) or not cursor or cursor in seen:
219
+ raise SessionError('Codex returned an invalid turn-history cursor')
220
+ seen.add(cursor)
221
+ raise SessionError('The owned turn was not found in bounded history; recovery is required')
222
+
223
+ @staticmethod
224
+ def _inputs(scope, text, context):
225
+ inputs = [{'type':'text','text':text}]
226
+ if context is not None:
227
+ from .engineering_contexts import context_input
228
+ if context.get('projectId') != scope.project:
229
+ raise SessionError('Project context does not belong to this engineering session')
230
+ inputs.append(context_input(context))
231
+ return inputs
232
+
233
+ async def steer(self,scope,handle,turn,text,*,request_id=None,context=None):
234
+ client,_,_=self._owned(scope,handle)
235
+ await client.request('turn/steer',{'threadId':handle,'expectedTurnId':turn,
236
+ 'input':self._inputs(scope, text, context),
237
+ **({'clientUserMessageId':request_id} if request_id is not None else {})})
238
+
239
+ async def interrupt(self,scope,handle,turn):
240
+ client,_,_=self._owned(scope,handle)
241
+ await client.request('turn/interrupt',{'threadId':handle,'turnId':turn})
242
+
243
+ async def next_event(self,scope,handle):
244
+ client,_,_=self._owned(scope,handle)
245
+ while True:
246
+ message=await client.notification()
247
+ method=message.get('method');params=message.get('params',{})
248
+ if params.get('threadId') not in (None,handle):
249
+ raise SessionError('Codex notification belongs to another thread')
250
+ if method=='turn/completed':
251
+ turn=params.get('turn',{});status=turn.get('status')
252
+ if status not in {'completed','failed','interrupted'}:
253
+ raise SessionError('Codex returned an unknown terminal turn status')
254
+ return BackendEvent(turn.get('id'),status)
255
+ if method=='item/agentMessage/delta':
256
+ return BackendEvent(params.get('turnId'),'message',params.get('delta',''))
257
+ if method in {'item/started','item/completed'}:
258
+ item=params.get('item',{})
259
+ if params.get('turnId'):
260
+ # Tool summaries are progress, never successful validation.
261
+ return BackendEvent(params['turnId'],'progress',str(item.get('type','work')))
262
+
263
+ async def close(self):
264
+ rows=list(self.clients.values());self.clients.clear()
265
+ for client,_,_ in rows:
266
+ await client.close()
@@ -0,0 +1,193 @@
1
+ """Trusted local worker policy, separate from browser input and model selection.
2
+
3
+ This constrains native local commands, not a hosted OS/tenant boundary. Only
4
+ control-plane selected tool directories may be added as read roots. Do not pass
5
+ client paths, source repositories or credential directories here.
6
+ """
7
+ import json
8
+ import os
9
+ import re
10
+ from pathlib import Path
11
+ import shutil
12
+ import tomllib
13
+ import platform
14
+ import sys
15
+
16
+ from .codex_app_server import CodexAppServer
17
+
18
+ PROFILE = 'atmem-engineering-v2'
19
+
20
+
21
+ def configured_mcp_names():
22
+ """Inspect names only; never copy credentials or server definitions.
23
+
24
+ An empty table override merges with the user's existing table in current
25
+ Codex versions. Explicitly disable known entries; the live worker check must
26
+ still reject any server introduced by another effective configuration layer.
27
+ """
28
+ names=set()
29
+ paths=[Path('/etc/codex/config.toml'),Path(os.getenv('CODEX_HOME',str(Path.home()/'.codex')))/'config.toml']
30
+ def collect(value):
31
+ if not isinstance(value,dict):return
32
+ servers=value.get('mcp_servers',{})
33
+ if isinstance(servers,dict):names.update(servers)
34
+ for nested in value.values():
35
+ if isinstance(nested,dict):collect(nested)
36
+ for path in paths:
37
+ if path.exists():
38
+ with path.open('rb') as source:collect(tomllib.load(source))
39
+ return sorted(names)
40
+
41
+
42
+ def configured_shell_override_names():
43
+ """Return keys to blank in the worker; never forward their original values."""
44
+ names=set()
45
+ paths=[Path('/etc/codex/config.toml'),Path(os.getenv('CODEX_HOME',str(Path.home()/'.codex')))/'config.toml']
46
+ def collect(value):
47
+ if not isinstance(value,dict):return
48
+ policy=value.get('shell_environment_policy',{})
49
+ if isinstance(policy,dict) and isinstance(policy.get('set',{}),dict):names.update(policy.get('set',{}))
50
+ for nested in value.values():
51
+ if isinstance(nested,dict):collect(nested)
52
+ for path in paths:
53
+ if path.exists():
54
+ with path.open('rb') as source:collect(tomllib.load(source))
55
+ return sorted(names)
56
+
57
+
58
+ def native_codex(executable):
59
+ """Resolve the official npm native binary so sandbox helpers see their code tree."""
60
+ selected=Path(executable).resolve(strict=True)
61
+ package=selected.parent.parent
62
+ if selected.suffix.lower()=='.cmd':
63
+ package=selected.parent/'node_modules/@openai/codex'
64
+ metadata=package/'package.json'
65
+ try:
66
+ if json.loads(metadata.read_text(encoding='utf-8')).get('name')!='@openai/codex':return selected,selected.parent
67
+ except (OSError,ValueError):return selected,selected.parent
68
+ arch={'x86_64':'x64','AMD64':'x64','aarch64':'arm64','arm64':'arm64'}.get(platform.machine())
69
+ targets={('linux','x64'):('linux-x64','x86_64-unknown-linux-musl'),('linux','arm64'):('linux-arm64','aarch64-unknown-linux-musl'),('darwin','x64'):('darwin-x64','x86_64-apple-darwin'),('darwin','arm64'):('darwin-arm64','aarch64-apple-darwin'),('win32','x64'):('win32-x64','x86_64-pc-windows-msvc'),('win32','arm64'):('win32-arm64','aarch64-pc-windows-msvc')}
70
+ target=targets.get((sys.platform,arch))
71
+ if not target:raise RuntimeError('This Codex native target is unsupported')
72
+ suffix,triple=target
73
+ for vendor in [package.parent/('codex-'+suffix)/'vendor',package/'vendor']:
74
+ candidate=vendor/triple/'bin'/('codex.exe'if os.name=='nt'else'codex')
75
+ if candidate.is_file():return candidate.resolve(strict=True),candidate.parent.parent.resolve(strict=True)
76
+ raise RuntimeError('The Codex npm installation is missing its platform binary; reinstall the official client')
77
+
78
+
79
+ def worker_command(read_roots=(),*,temporary_dir=None):
80
+ executable = shutil.which('codex')
81
+ if not executable:
82
+ raise RuntimeError('The selected native worker is unavailable')
83
+ binary, native_root = native_codex(executable)
84
+ # Include the symlink's directory and native package tree so the CLI's
85
+ # sandbox helper can execute. These are code paths, not its auth/state home.
86
+ roots = {Path(executable).parent.resolve(), native_root}
87
+ for root in read_roots:
88
+ path = Path(root).resolve(strict=True)
89
+ if not path.is_dir():
90
+ raise ValueError('A worker tool read root must be an existing directory')
91
+ secrets = [Path.home()/name for name in ['.codex','.aws','.ssh','.kube']]
92
+ if Path.home().is_relative_to(path) or any(path.is_relative_to(p) or p.is_relative_to(path) for p in secrets):
93
+ raise ValueError('Worker tools cannot expose a home or credential tree')
94
+ roots.add(path)
95
+ forbidden = {Path('/'), Path.home(), Path.home()/'.codex', Path.home()/'.aws', Path.home()/'.ssh'}
96
+ if roots & forbidden:
97
+ raise ValueError('Worker tool roots cannot grant filesystem, home or credential trees')
98
+ entries = {':root':'deny', ':minimal':'read', ':tmpdir':'deny', ':slash_tmp':'deny'}
99
+ entries.update({str(p):'read' for p in sorted(roots)})
100
+ filesystem = ','.join(f'{json.dumps(k)}={json.dumps(v)}' for k,v in entries.items())
101
+ # The native proxy must be active to propagate its Unix-socket allowlist.
102
+ # No domain is allowed, local binding is forbidden and raw IP access remains
103
+ # sandboxed. The profile's enabled flag is not an unrestricted network grant.
104
+ network='enabled=true,domains={},proxy_url="http://127.0.0.1:0",enable_socks5=false,allow_local_binding=false'
105
+ if temporary_dir is not None:
106
+ # Terraform's provider protocol binds random AF_UNIX sockets beneath its
107
+ # private temp directory. Permit only that subtree, never Docker/host IPC
108
+ # or IP networking. This must be requalified per native worker platform.
109
+ network+=',unix_sockets={'+json.dumps(str(temporary_dir))+'="allow"}'
110
+ definition = f'permissions.{PROFILE}={{extends=":workspace",filesystem={{{filesystem}}},network={{{network}}}}}'
111
+ command = [str(binary),'app-server','--listen','stdio://',
112
+ '-c','analytics.enabled=false','-c',definition,
113
+ '-c',f'default_permissions={json.dumps(PROFILE)}',
114
+ '-c','shell_environment_policy.inherit="core"',
115
+ '-c','shell_environment_policy.ignore_default_excludes=false',
116
+ '-c','allow_login_shell=false','-c','features.shell_snapshot=false',
117
+ '-c','features.network_proxy=true',
118
+ '-c','mcp_servers={}','-c','features.apps=false','-c','features.plugins=false',
119
+ '-c','web_search="disabled"']
120
+ if temporary_dir is not None:
121
+ command.extend(['-c',f'shell_environment_policy.set.TMPDIR={json.dumps(str(temporary_dir))}'])
122
+ for name in configured_mcp_names():
123
+ # CLI override dotted paths do not parse TOML quotes in key segments.
124
+ # Refuse unusual keys rather than creating a second, ineffective entry.
125
+ if not re.fullmatch(r'[A-Za-z0-9_-]+',name):
126
+ raise ValueError('An MCP configuration key cannot be disabled safely by this worker')
127
+ command.extend(['-c',f'mcp_servers.{name}.enabled=false'])
128
+ for name in configured_shell_override_names():
129
+ if name=='TMPDIR':continue
130
+ if not re.fullmatch(r'[A-Za-z_][A-Za-z0-9_]*',name):
131
+ raise ValueError('A shell override key cannot be disabled safely by this worker')
132
+ command.extend(['-c',f'shell_environment_policy.set.{name}=""'])
133
+ return command
134
+
135
+
136
+ class CodexWorkerClient(CodexAppServer):
137
+ def __init__(self,workspace,*,read_roots=(),requires_unix_sockets=True):
138
+ root=Path(workspace).resolve(strict=True)
139
+ temporary=root/'.worker-tmp'
140
+ if requires_unix_sockets and os.name=='posix' and len(os.fsencode(temporary))>80:
141
+ raise ValueError('Register a shorter worker workspace path for Unix-socket validators')
142
+ if temporary.is_symlink():
143
+ raise ValueError('Worker temporary storage cannot be a symlink')
144
+ temporary.mkdir(exist_ok=True)
145
+ command=worker_command(read_roots,temporary_dir=temporary)
146
+ definition=next(value for value in command if value.startswith(f'permissions.{PROFILE}='))
147
+ self.expected_worker_profile=tomllib.loads(definition)['permissions'][PROFILE]
148
+ super().__init__(root,command=command,experimental=True)
149
+
150
+ async def verify_worker_tools(self,expected_profile=PROFILE):
151
+ if expected_profile!=PROFILE:
152
+ raise RuntimeError('This worker cannot attest a different named permission profile')
153
+ effective=await self.request('config/read',{'includeLayers':False,'cwd':str(self.workspace)})
154
+ config=effective.get('config')
155
+ if not isinstance(config,dict):
156
+ raise RuntimeError('Worker configuration acknowledgement is unavailable')
157
+ definitions=config.get('mcp_servers',{})
158
+ if not isinstance(definitions,dict) or any(not isinstance(v,dict) or v.get('enabled') is not False for v in definitions.values()):
159
+ raise RuntimeError('Unapproved MCP enablement is present in this local worker')
160
+ features=config.get('features',{})
161
+ if not isinstance(features,dict) or features.get('apps') is not False or features.get('plugins') is not False or config.get('web_search')!='disabled':
162
+ raise RuntimeError('External tools were not disabled in this local worker')
163
+ shell=config.get('shell_environment_policy',{})
164
+ if config.get('allow_login_shell') is not False or features.get('shell_snapshot') is not False or not isinstance(shell,dict) or shell.get('inherit')!='core' or shell.get('ignore_default_excludes') is not False or shell.get('include_only') not in (None,[]):
165
+ raise RuntimeError('The restricted worker shell environment was not confirmed')
166
+ overrides=shell.get('set')
167
+ if not isinstance(overrides,dict) or overrides.get('TMPDIR')!=str(self.workspace/'.worker-tmp') or any(k!='TMPDIR' and v!='' for k,v in overrides.items()):
168
+ raise RuntimeError('Unexpected inherited shell variable overrides were configured')
169
+ profile=config.get('permissions',{}).get(PROFILE,{})
170
+ network=profile.get('network',{})
171
+ if features.get('network_proxy') is not True or network.get('enabled') is not True or network.get('domains') not in ({},None) or network.get('allow_local_binding') is not False:
172
+ raise RuntimeError('The deny-all worker proxy was not confirmed')
173
+ filesystem=profile.get('filesystem')
174
+ if isinstance(filesystem,dict):
175
+ filesystem=dict(filesystem)
176
+ if filesystem.get('glob_scan_max_depth') is None:filesystem.pop('glob_scan_max_depth',None)
177
+ if profile.get('extends')!=':workspace' or filesystem!=self.expected_worker_profile['filesystem']:
178
+ raise RuntimeError('The worker filesystem policy changed in an effective configuration layer')
179
+ if network.get('unix_sockets')!=self.expected_worker_profile['network'].get('unix_sockets') or network.get('dangerously_allow_all_unix_sockets') is True or network.get('dangerously_allow_non_loopback_proxy') is True:
180
+ raise RuntimeError('Unexpected local socket access was added to the worker')
181
+ roots=profile.get('workspace_roots',{}) or {}
182
+ if not isinstance(roots,dict) or any(value is not False for value in roots.values()):
183
+ raise RuntimeError('Unexpected profile-owned workspace roots were added')
184
+ result=await self.request('mcpServerStatus/list',{'limit':100})
185
+ states=result.get('data')
186
+ if not isinstance(states,list) or result.get('nextCursor'):
187
+ raise RuntimeError('Unapproved MCP tools are configured in this local worker')
188
+ # The status API lists disabled definitions too. Require both effective
189
+ # disabled configuration and no initialized server/tool/resource surface.
190
+ for state in states:
191
+ if not isinstance(state,dict) or state.get('name') not in definitions or state.get('runtimeStatus') is not None or state.get('tools')!={} or state.get('resources')!=[] or state.get('resourceTemplates')!=[]:
192
+ raise RuntimeError('An MCP server exposed tools or resources in this local worker')
193
+ return {'configuredMcpDefinitions':len(definitions),'allDisabled':True,'exposedMcpTools':0,'apps':False,'plugins':False,'webSearch':'disabled'}