@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,185 @@
1
+ """Supported local CLI account adapters. No account token extraction or custom OAuth."""
2
+ import asyncio, base64, json, os, shutil, signal, sys, tempfile
3
+ from pathlib import Path
4
+
5
+ SIGN_IN={'claude-code':('claude','claude auth login'),'codex':('codex','codex login'),'gemini-cli':('gemini','gemini'),'copilot':('copilot','copilot login')}
6
+
7
+ def cli_command(argv):
8
+ """Resolve PATHEXT shims explicitly; CreateProcess does not search .cmd names."""
9
+ return [shutil.which(argv[0]) or argv[0], *argv[1:]]
10
+
11
+ def account_environment():
12
+ env=dict(os.environ)
13
+ for key in ['ANTHROPIC_API_KEY','ANTHROPIC_AUTH_TOKEN','OPENAI_API_KEY','CODEX_API_KEY','GEMINI_API_KEY','GOOGLE_API_KEY','GITHUB_TOKEN','GH_TOKEN','COPILOT_GITHUB_TOKEN']:
14
+ env.pop(key,None)
15
+ return env
16
+
17
+ # Official sign-in, started from the app: each CLI opens its provider's own page in the browser.
18
+ LOGIN={'claude-code':['claude','auth','login'],'codex':['codex','login'],'copilot':['copilot','login']}
19
+ STATUS={'claude-code':['claude','auth','status','--json'],'codex':['codex','login','status']}
20
+ LOGINS={}
21
+
22
+ def signed_in(provider):
23
+ """True/False when the CLI can tell us, None when it can't."""
24
+ argv=STATUS.get(provider)
25
+ if not argv or not shutil.which(argv[0]):return None
26
+ import subprocess
27
+ try:
28
+ done=subprocess.run(cli_command(argv),capture_output=True,text=True,encoding='utf-8',errors='replace',timeout=8,stdin=subprocess.DEVNULL,env=account_environment())
29
+ except Exception:
30
+ return None
31
+ if provider=='claude-code':
32
+ try:return bool(json.loads(done.stdout).get('loggedIn'))
33
+ except Exception:return None
34
+ return done.returncode==0 and 'logged in' in (done.stdout+done.stderr).lower()
35
+
36
+ def capabilities():
37
+ return {key:{'available':bool(shutil.which(binary)),'installed':bool(shutil.which(binary)),'loginCommand':command,'canSignInFromApp':key in LOGIN,
38
+ 'signedIn':signed_in(key) if shutil.which(binary) else False} for key,(binary,command) in SIGN_IN.items()}
39
+
40
+ async def start_login(provider):
41
+ """Start the provider's official login; return a sign-in URL if the CLI prints one."""
42
+ import re
43
+ argv=LOGIN.get(provider)
44
+ if not argv or not shutil.which(argv[0]):raise RuntimeError('This provider has no sign-in AtMem AI Architect can start. Use its API key instead.')
45
+ running=LOGINS.get(provider)
46
+ if running and running.returncode is None:return {'started':True,'url':None}
47
+ process=await asyncio.create_subprocess_exec(*cli_command(argv),stdin=asyncio.subprocess.DEVNULL,stdout=asyncio.subprocess.PIPE,stderr=asyncio.subprocess.STDOUT,env=account_environment(),start_new_session=os.name!='nt')
48
+ LOGINS[provider]=process
49
+ url=None
50
+ try:
51
+ deadline=asyncio.get_running_loop().time()+6
52
+ while asyncio.get_running_loop().time()<deadline and url is None:
53
+ line=await asyncio.wait_for(process.stdout.readline(),timeout=max(.1,deadline-asyncio.get_running_loop().time()))
54
+ if not line:break
55
+ found=re.search(r'https://\S+',line.decode(errors='ignore'))
56
+ if found:url=found.group(0).rstrip('.,)')
57
+ except asyncio.TimeoutError:pass
58
+ # Keep draining output so the CLI can finish its callback; don't block the request.
59
+ async def drain():
60
+ try:
61
+ while await process.stdout.read(4096):pass
62
+ except Exception:pass
63
+ asyncio.create_task(drain())
64
+ return {'started':True,'url':url}
65
+
66
+ def extract_json(text):
67
+ text=text.strip()
68
+ if text.startswith('```'):text='\n'.join(text.splitlines()[1:-1])
69
+ return json.loads(text)
70
+
71
+ def strict_schema(schema):
72
+ """Codex structured output requires every declared object field to be required."""
73
+ schema=json.loads(json.dumps(schema))
74
+ def visit(value):
75
+ if isinstance(value,dict):
76
+ if value.get('type')=='object' and 'properties' in value:value['required']=list(value['properties']);value['additionalProperties']=False
77
+ for child in value.values():visit(child)
78
+ elif isinstance(value,list):
79
+ for child in value:visit(child)
80
+ visit(schema);return schema
81
+
82
+ def provider_failure(output=b'',error=b''):
83
+ """Classify provider errors without exposing raw CLI output or account details."""
84
+ text=(output.decode(errors='replace') if isinstance(output,bytes) else str(output))+' '+(error.decode(errors='replace') if isinstance(error,bytes) else str(error))
85
+ text=text[:64000].lower()
86
+ if any(term in text for term in ['session limit','usage limit','hit your limit','rate limit','rate_limit','insufficient_quota','credit balance','too many requests']):
87
+ return 'The selected architect has reached its usage or rate limit. Wait for the provider reset or choose another connected architect. Your design is preserved; no correction was applied.'
88
+ if any(term in text for term in ['not logged in','authentication failed','invalid api key','unauthorized','login required']):
89
+ return 'The selected architect needs you to sign in again through its official client or update its API connection. Your design is preserved.'
90
+ if any(term in text for term in ['model not found','model_not_found','model is not available']):
91
+ return 'That model is not available to the selected account. Choose an accessible model in Connections. Your design is preserved.'
92
+ return 'Provider request failed. Check its official CLI sign-in, model access and usage limits. No changes were applied.'
93
+
94
+ async def communicate(argv,prompt,cwd,is_disconnected,env=None,timeout=150):
95
+ process=await asyncio.create_subprocess_exec(*argv,stdin=asyncio.subprocess.PIPE,stdout=asyncio.subprocess.PIPE,stderr=asyncio.subprocess.PIPE,cwd=cwd,env=env,start_new_session=os.name!='nt')
96
+ task=asyncio.create_task(process.communicate(prompt.encode()))
97
+ deadline=asyncio.get_running_loop().time()+timeout
98
+ try:
99
+ while not task.done():
100
+ if await is_disconnected():raise asyncio.CancelledError()
101
+ if asyncio.get_running_loop().time()>deadline:raise TimeoutError('Architect request timed out.')
102
+ await asyncio.sleep(.2)
103
+ output,error=await task
104
+ if process.returncode:raise RuntimeError(provider_failure(output,error))
105
+ return output.decode()
106
+ finally:
107
+ if process.returncode is None:
108
+ try:
109
+ if os.name=='nt':process.terminate()
110
+ else:os.killpg(process.pid,signal.SIGTERM)
111
+ except ProcessLookupError:pass
112
+ try:await asyncio.wait_for(process.wait(),3)
113
+ except asyncio.TimeoutError:
114
+ try:
115
+ if os.name=='nt':process.kill()
116
+ else:os.killpg(process.pid,signal.SIGKILL)
117
+ except ProcessLookupError:pass
118
+ await process.wait()
119
+ if not task.done():task.cancel()
120
+ try:await task
121
+ except (asyncio.CancelledError,Exception):pass
122
+
123
+ CLAUDE_EFFORTS=['low','medium','high','xhigh','max']
124
+ # Claude Code accepts these model names; the list matches the current Claude family.
125
+ CLAUDE_MODELS=[('claude-opus-5-5','Opus 5.5'),('claude-fable-5-1','Fable 5.1'),('claude-sonnet-5','Sonnet 5'),('claude-haiku-4-5-20251001','Haiku 4.5')]
126
+ COPILOT_EFFORTS=['low','medium','high','xhigh','max']
127
+
128
+ def models(provider):
129
+ """Models and thinking levels the provider's own CLI reports; empty list means type an ID."""
130
+ import subprocess
131
+ if provider=='claude-code':
132
+ return [{'id':i,'name':n,'efforts':CLAUDE_EFFORTS,'defaultEffort':'medium'} for i,n in CLAUDE_MODELS]
133
+ if provider=='codex' and shutil.which('codex'):
134
+ try:
135
+ done=subprocess.run(cli_command(['codex','debug','models']),capture_output=True,text=True,encoding='utf-8',errors='replace',timeout=15,stdin=subprocess.DEVNULL,env=account_environment())
136
+ data=json.loads(done.stdout)
137
+ return [{'id':m['slug'],'name':m.get('display_name',m['slug']),'efforts':[e['effort'] for e in m.get('supported_reasoning_levels',[])],'defaultEffort':m.get('default_reasoning_level')}
138
+ for m in data.get('models',[]) if m.get('visibility','list')=='list']
139
+ except Exception:
140
+ return []
141
+ if provider=='gemini-cli' and shutil.which('gemini'):
142
+ return [{'id':'auto','name':'Gemini CLI (your configured model)','efforts':[],'defaultEffort':None}]
143
+ if provider=='copilot':
144
+ # The Copilot SDK path doesn't take a thinking level yet; offer only what we can honour.
145
+ return [{'id':'auto','name':'Auto (Copilot picks)','efforts':[],'defaultEffort':None}]
146
+ return []
147
+
148
+ async def call_cli(provider,model,prompt,system,schema,is_disconnected,effort=None,images=None,timeout=150):
149
+ binary=shutil.which(SIGN_IN[provider][0])
150
+ if not binary:raise RuntimeError(f'Install and sign in with {SIGN_IN[provider][0]} first, or choose an API key.')
151
+ with tempfile.TemporaryDirectory(prefix='atforma-agent-') as cwd:
152
+ env=account_environment()
153
+ if provider=='claude-code':
154
+ args=[binary,'-p','--safe-mode','--strict-mcp-config','--tools','','--no-session-persistence','--output-format','json','--json-schema',json.dumps(schema),'--system-prompt',system]
155
+ if model not in ('default','auto'):args+=['--model',model]
156
+ if effort in CLAUDE_EFFORTS:args+=['--effort',effort]
157
+ if images:
158
+ args+=['--input-format','stream-json']
159
+ content=[{'type':'text','text':prompt}]+[{'type':'image','source':{'type':'base64','media_type':i['mime'],'data':i['data']}} for i in images]
160
+ prompt=json.dumps({'type':'user','message':{'role':'user','content':content}})+'\n'
161
+ result=json.loads(await communicate(args,prompt,cwd,is_disconnected,env,timeout=timeout))
162
+ if result.get('is_error'):raise RuntimeError(provider_failure(json.dumps(result)))
163
+ return result.get('structured_output') or extract_json(result.get('result',''))
164
+ if provider=='codex':
165
+ schema_path=Path(cwd)/'response-schema.json';schema_path.write_text(json.dumps(strict_schema(schema)))
166
+ args=[binary,'exec','--sandbox','read-only','--skip-git-repo-check','--ephemeral','--ignore-user-config','--ignore-rules','--disable','shell_tool','--disable','unified_exec','--disable','plugins','--disable','apps','--disable','browser_use','--disable','in_app_browser','--disable','code_mode_host','-c','approval_policy="never"','-c','web_search="disabled"','--output-schema',str(schema_path),'--color','never','-']
167
+ for index,item in enumerate(images or []):
168
+ image_path=Path(cwd)/f'attachment-{index}.{item["mime"].split("/")[1]}'
169
+ image_path.write_bytes(base64.b64decode(item['data']));image_path.chmod(0o600)
170
+ args+=['--image',str(image_path)]
171
+ if model not in ('default','auto'):args+=['--model',model]
172
+ if effort:args+=['-c',f'model_reasoning_effort="{effort}"']
173
+ return extract_json(await communicate(args,system+'\n\n'+prompt,cwd,is_disconnected,env,timeout=timeout))
174
+ if provider=='gemini-cli':
175
+ settings=Path(cwd)/'settings.json';settings.write_text(json.dumps({'tools':{'core':[]},'hooksConfig':{'enabled':False},'mcp':{'allowed':['atforma-no-servers']},'telemetry':{'enabled':False},'general':{'enableAutoUpdate':False,'sessionRetention':{'enabled':False}}}))
176
+ env['GEMINI_CLI_SYSTEM_SETTINGS_PATH']=str(settings)
177
+ policy=Path(cwd)/'deny-tools.toml';policy.write_text('[[rule]]\ntoolName = "*"\ndecision = "deny"\npriority = 999\n')
178
+ args=[binary,'--prompt',system,'--output-format','json','--approval-mode','plan','--extensions','none','--allowed-mcp-server-names','atforma-no-servers','--policy',str(policy)]
179
+ if model not in ('default','auto'):args+=['--model',model]
180
+ result=json.loads(await communicate(args,prompt,cwd,is_disconnected,env,timeout=timeout))
181
+ if result.get('error'):raise RuntimeError('Gemini request failed. Run gemini to sign in and check your model access.')
182
+ return extract_json(result.get('response',''))
183
+ # Official Copilot SDK provides tool exclusion and permission denial without --allow-all.
184
+ worker=Path(__file__).with_name('copilot_worker.py')
185
+ return extract_json(await communicate([sys.executable,str(worker)],json.dumps({'prompt':prompt,'system':system,'schema':strict_schema(schema),'model':model,'cwd':cwd,'cli':binary,'images':images or []}),cwd,is_disconnected,env,timeout=timeout))
@@ -0,0 +1,236 @@
1
+ """Trusted controller for digest-bound local checks, outside the model worker.
2
+
3
+ No public/raw-command endpoint. Operator-reviewed specs select cached immutable
4
+ images and commands. Artifacts travel over stdin; no host directory/socket or
5
+ credential is mounted. Container loopback works, external/host networking does not.
6
+ This executes checks; requirement acceptance needs separately authored oracles.
7
+ """
8
+ from dataclasses import dataclass
9
+ import hashlib
10
+ import json
11
+ import os
12
+ from pathlib import Path
13
+ import re
14
+ import subprocess
15
+ import tempfile
16
+ import threading
17
+ import time
18
+ import uuid
19
+
20
+
21
+ # Only trusted bootstrap code runs with SETUID/SETGID. Untrusted source is copied as
22
+ # root-owned read-only files, then all supplementary groups/root identity are dropped
23
+ # before exec. Changing UID clears effective capabilities; no-new-privileges prevents
24
+ # reacquisition. This policy requires native Linux-container qualification below.
25
+ BOOTSTRAP = r'''
26
+ import hashlib,io,json,os,pathlib,stat,sys,zipfile
27
+ expected,command=json.loads(sys.argv[1])
28
+ content=sys.stdin.buffer.read(64000001)
29
+ if len(content)>64000000 or hashlib.sha256(content).hexdigest()!=expected:
30
+ raise RuntimeError('Immutable artifact digest/size mismatch')
31
+ root=pathlib.Path('/work/source');root.mkdir()
32
+ with zipfile.ZipFile(io.BytesIO(content)) as archive:
33
+ entries=archive.infolist()
34
+ if len(entries)>2000 or sum(e.file_size for e in entries)>64000000:
35
+ raise RuntimeError('Artifact bounds exceeded')
36
+ seen=set()
37
+ for entry in entries:
38
+ path=pathlib.PurePosixPath(entry.filename)
39
+ if path.is_absolute() or '..' in path.parts or '\\' in entry.filename or any(ord(c)<32 for c in entry.filename) or not path.parts or str(path) in seen:
40
+ raise RuntimeError('Unsafe or duplicate archive entry')
41
+ seen.add(str(path));mode=entry.external_attr>>16
42
+ if stat.S_IFMT(mode) not in (0,stat.S_IFREG,stat.S_IFDIR):
43
+ raise RuntimeError('Linked/special archive entry')
44
+ target=root.joinpath(*path.parts)
45
+ if entry.is_dir():target.mkdir(parents=True,exist_ok=True)
46
+ else:
47
+ target.parent.mkdir(parents=True,exist_ok=True)
48
+ target.write_bytes(archive.read(entry))
49
+ target.chmod(0o555 if mode & 0o111 else 0o444)
50
+ for directory in sorted((p for p in root.rglob('*') if p.is_dir()),reverse=True):directory.chmod(0o555)
51
+ root.chmod(0o555)
52
+ os.chdir(root)
53
+ os.setgroups([]);os.setgid(65532);os.setuid(65532)
54
+ if os.getuid()!=65532 or os.getgid()!=65532:raise RuntimeError('Validator identity was not dropped')
55
+ os.execv(command[0],command)
56
+ '''
57
+
58
+
59
+ @dataclass(frozen=True)
60
+ class ValidationSpec:
61
+ name: str
62
+ image: str
63
+ command: tuple[str, ...]
64
+ platform: str = 'linux/amd64'
65
+ timeout_seconds: int = 60
66
+ bootstrap_python: str = '/usr/local/bin/python3'
67
+ isolation_profile: str = 'standard-v1'
68
+ runtime_environment: tuple[tuple[str,str], ...] = ()
69
+ executable_scratch: bool = False
70
+
71
+ def __post_init__(self):
72
+ if not isinstance(self.name,str) or not re.fullmatch(r'[a-z][a-z0-9_-]{2,79}',self.name):raise ValueError('Invalid trusted validator name')
73
+ if not isinstance(self.image,str) or not re.fullmatch(r'sha256:[a-f0-9]{64}',self.image):raise ValueError('Use a cached immutable image ID')
74
+ if self.platform not in {'linux/amd64','linux/arm64'}:raise ValueError('Unqualified container platform')
75
+ if not isinstance(self.command,tuple) or not self.command or not all(isinstance(x,str) and x and '\0' not in x for x in self.command) or not self.command[0].startswith('/'):
76
+ raise ValueError('Register an explicit trusted validator executable/argument vector')
77
+ if type(self.timeout_seconds) is not int or not 1<=self.timeout_seconds<=300:raise ValueError('Validator time budget must be bounded')
78
+ if not isinstance(self.bootstrap_python,str) or not self.bootstrap_python.startswith('/') or '\0' in self.bootstrap_python:
79
+ raise ValueError('Register an absolute Python bootstrap executable in the reviewed image')
80
+ if self.isolation_profile not in {'standard-v1','chromium-userns-v1','postgresql-local-v1'}:raise ValueError('Unreviewed validator isolation profile')
81
+ if type(self.executable_scratch)is not bool:raise ValueError('Executable dependency scratch requires an explicit operator boolean')
82
+ if self.executable_scratch and self.isolation_profile=='chromium-userns-v1':raise ValueError('Executable dependency scratch is not qualified with the browser profile')
83
+ if not isinstance(self.runtime_environment,tuple) or any(not isinstance(pair,tuple) or len(pair)!=2 or not isinstance(pair[0],str) or pair[0] not in {'ATMEM_PLAYWRIGHT_MODULE','PLAYWRIGHT_BROWSERS_PATH'} or not isinstance(pair[1],str) or not pair[1].startswith('/') or any(ord(c)<32 for c in pair[1]) for pair in self.runtime_environment) or len({pair[0] for pair in self.runtime_environment})!=len(self.runtime_environment):
84
+ raise ValueError('Register only explicit image-local runtime module/browser paths')
85
+
86
+
87
+ def validation_test_runner(spec):
88
+ command=spec.command
89
+ if spec.isolation_profile=='postgresql-local-v1' and command[1:3]==('-I','/opt/atmem/sql_validation.py'):
90
+ command=(command[0],*command[3:])
91
+ if command[1:3]==('-m','unittest'):return 'unittest'
92
+ if Path(command[0]).name in {'node','nodejs'}and command[1:2]==('--test',):return 'node:test'
93
+ return 'operator_registered'
94
+
95
+
96
+ class DockerValidationWorker:
97
+ REVIEWED_PROFILES={'chromium-userns-v1':'e53c15d248f57bceec0a3a16fad1b4ab0d05a7bddb455f86a60e2dba5612cdf7'}
98
+
99
+ def __init__(self, endpoint, *, binary='docker', max_output_bytes=256000, isolation_profiles=None):
100
+ if not isinstance(endpoint,str) or not endpoint.startswith('unix:///') or not Path(endpoint[7:]).is_socket():
101
+ raise ValueError('Use an explicitly registered local Docker Unix socket')
102
+ if type(max_output_bytes) is not int or not 1024<=max_output_bytes<=1000000:
103
+ raise ValueError('Validator output budget must be bounded')
104
+ self.endpoint,self.binary,self.max_output_bytes=endpoint,binary,max_output_bytes
105
+ profiles={} if isolation_profiles is None else isolation_profiles
106
+ if not isinstance(profiles,dict) or set(profiles)-set(self.REVIEWED_PROFILES):raise ValueError('Register reviewed isolation profiles only')
107
+ self.isolation_profiles={}
108
+ for name,entry in profiles.items():
109
+ if not isinstance(entry,dict) or set(entry)!={'path','sha256'} or entry['sha256']!=self.REVIEWED_PROFILES[name] or not isinstance(entry['path'],str) or not Path(entry['path']).is_absolute() or Path(entry['path']).is_symlink():raise ValueError('A reviewed pinned local isolation policy is required')
110
+ if Path(entry['path']).stat().st_size>64000:raise ValueError('Isolation policy exceeds its explicit size limit')
111
+ content=Path(entry['path']).read_bytes()
112
+ if len(content)>64000 or hashlib.sha256(content).hexdigest()!=entry['sha256'] or json.loads(content).get('defaultAction')!='SCMP_ACT_ERRNO':raise ValueError('Isolation policy does not match its reviewed bytes')
113
+ self.isolation_profiles[name]=content
114
+ self.policy_digest=hashlib.sha256(json.dumps({'code':hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),'profiles':{name:hashlib.sha256(content).hexdigest() for name,content in self.isolation_profiles.items()}},sort_keys=True).encode()).hexdigest()
115
+ self.identity_digest=hashlib.sha256(endpoint.encode()).hexdigest()
116
+
117
+ def supports(self,spec):return spec.isolation_profile in {'standard-v1','postgresql-local-v1'} or spec.isolation_profile in self.isolation_profiles
118
+
119
+ def run(self, archive, expected_digest, spec: ValidationSpec, *, execution_id=None, cancel_event=None):
120
+ if not isinstance(archive,bytes) or len(archive)>64000000 or hashlib.sha256(archive).hexdigest()!=expected_digest:
121
+ raise ValueError('Digest-bound artifact bytes are required')
122
+ if not self.supports(spec):raise RuntimeError('The reviewed isolation profile is unavailable; no fallback was used')
123
+ execution=uuid.UUID(execution_id) if execution_id is not None else uuid.uuid4()
124
+ ident='atmem-validator-'+execution.hex
125
+ started=time.monotonic()
126
+ with tempfile.TemporaryDirectory(prefix='atmem-validator-control-') as folder:
127
+ config=Path(folder)/'docker';config.mkdir()
128
+ (config/'config.json').write_text('{}')
129
+ env={'PATH':os.environ.get('PATH',''),'HOME':folder,'DOCKER_CONFIG':str(config),'DOCKER_HOST':self.endpoint}
130
+ prefix=[self.binary,'--host',self.endpoint,'--config',str(config)]
131
+ # Local image lookup only: never pull or evaluate a model Dockerfile.
132
+ inspect=subprocess.run([*prefix,'image','inspect',spec.image,'--format','{{.Id}}'],
133
+ env=env,capture_output=True,text=True,timeout=15)
134
+ if inspect.returncode!=0 or inspect.stdout.strip()!=spec.image:
135
+ raise RuntimeError('The reviewed local image/platform is unavailable; no image was pulled')
136
+ platform=subprocess.run([*prefix,'image','inspect','--platform',spec.platform,spec.image,'--format','{{.Os}}/{{.Architecture}} {{.Id}}'],
137
+ env=env,capture_output=True,text=True,timeout=15)
138
+ selection=platform.stdout.strip().split()
139
+ if platform.returncode!=0 or len(selection)!=2 or selection[0]!=spec.platform or not re.fullmatch(r'sha256:[a-f0-9]{64}',selection[1]):
140
+ raise RuntimeError('The reviewed cached platform is unavailable; no fallback or image pull was used')
141
+ browser=spec.isolation_profile=='chromium-userns-v1'
142
+ postgres=spec.isolation_profile=='postgresql-local-v1'
143
+ security=[]
144
+ if browser:
145
+ policy=Path(folder)/'reviewed-seccomp.json';policy.write_bytes(self.isolation_profiles[spec.isolation_profile])
146
+ security=['--security-opt','seccomp='+str(policy)]
147
+ runtime_env=[part for name,value in spec.runtime_environment for part in ['--env',name+'='+value]]
148
+ dependency_scratch=['--tmpfs','/dependencies:rw,exec,nosuid,nodev,size=128m,mode=1777','--env','TMPDIR=/dependencies','--env','ATMEM_TEST_DEPENDENCY_ROOT=/dependencies']if spec.executable_scratch else []
149
+ command=[*prefix,'run','--pull','never','--rm','--name',ident,'--platform',spec.platform,
150
+ '--network','none','--read-only','--cap-drop','ALL','--cap-add','SETUID','--cap-add','SETGID',
151
+ '--security-opt','no-new-privileges',*security,'--pids-limit','128' if browser else '64','--memory','512m' if browser or postgres else '256m','--cpus','1',
152
+ '--tmpfs','/work:rw,noexec,nosuid,nodev,size=128m,mode=0755',
153
+ '--tmpfs',f'/tmp:rw,noexec,nosuid,nodev,size={192 if postgres else 64 if browser else 32}m,mode=1777',
154
+ '--env','HOME=/tmp','--env','PYTHONDONTWRITEBYTECODE=1','--env','AWS_EC2_METADATA_DISABLED=true',
155
+ *runtime_env,*dependency_scratch,'--entrypoint',spec.bootstrap_python,'-i',spec.image,'-I','-c',BOOTSTRAP,
156
+ json.dumps([expected_digest,list(spec.command)])]
157
+ log=Path(folder)/'output.log'
158
+ reason=None
159
+ with log.open('wb') as output:
160
+ process=subprocess.Popen(command,env=env,stdin=subprocess.PIPE,stdout=output,stderr=subprocess.STDOUT)
161
+ def send():
162
+ try:process.stdin.write(archive)
163
+ except (BrokenPipeError,OSError):pass
164
+ finally:
165
+ try:process.stdin.close()
166
+ except (BrokenPipeError,OSError):pass
167
+ writer=threading.Thread(target=send,daemon=True);writer.start()
168
+ try:
169
+ while process.poll() is None:
170
+ if cancel_event is not None and cancel_event.is_set():reason='cancelled';break
171
+ if time.monotonic()-started>spec.timeout_seconds:reason='timeout';break
172
+ if log.stat().st_size>self.max_output_bytes:reason='output_limit';break
173
+ time.sleep(.05)
174
+ finally:
175
+ def cleanup():
176
+ nonlocal reason
177
+ try:
178
+ subprocess.run([*prefix,'rm','-f',ident],env=env,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,timeout=15)
179
+ except (OSError,subprocess.TimeoutExpired):reason='container_cleanup_unconfirmed'
180
+ if reason:
181
+ cleanup()
182
+ try:process.wait(timeout=10)
183
+ except subprocess.TimeoutExpired:process.kill();process.wait()
184
+ writer.join(timeout=2)
185
+ cleanup()
186
+ with log.open('rb') as output:raw=output.read(self.max_output_bytes+1)
187
+ truncated=len(raw)>self.max_output_bytes
188
+ text=raw[:self.max_output_bytes].decode('utf-8',errors='replace')
189
+ runner=validation_test_runner(spec)
190
+ unittest=runner=='unittest'
191
+ node_tests=runner=='node:test'
192
+ skips=re.search(r'OK \(skipped=(\d+)\)',text) if unittest else None
193
+ skipped=int(skips.group(1)) if skips else 0
194
+ count=re.search(r'Ran (\d+) tests? in ',text) if unittest else None
195
+ if node_tests:
196
+ totals=re.findall(r'^(?:#\s*|ℹ\s*)tests\s+(\d+)\s*$',text,re.MULTILINE)
197
+ skip_counts=re.findall(r'^(?:#\s*|ℹ\s*)skipped\s+(\d+)\s*$',text,re.MULTILINE)
198
+ executed=int(totals[-1]) if totals else None
199
+ skipped=int(skip_counts[-1]) if skip_counts else 0
200
+ else:executed=int(count.group(1)) if count else None
201
+ if postgres and process.returncode==69 and 'ATMEM_SQL_FIXTURE_UNAVAILABLE' in text and reason is None:
202
+ reason='sql_fixture_unavailable'
203
+ missing_tests=(unittest or node_tests) and (executed is None or executed==0)
204
+ status='failed' if reason or truncated or process.returncode or missing_tests else 'incomplete' if skipped else 'passed'
205
+ return {'validator':spec.name,'artifactSha256':expected_digest,'imageId':spec.image,
206
+ 'runtimeConfigImageId':selection[1],
207
+ 'platform':spec.platform,'isolationProfile':spec.isolation_profile,'runtimeEnvironment':dict(spec.runtime_environment),'command':list(spec.command),'status':status,'exitCode':process.returncode,
208
+ 'executableScratch':spec.executable_scratch,
209
+ 'skipped':skipped,'testsReported':executed,
210
+ 'reason':reason or ('output_limit' if truncated else 'no_tests_reported' if missing_tests else None),'output':text,
211
+ 'outputTruncated':truncated,'durationSeconds':round(time.monotonic()-started,3),
212
+ 'evidenceLevel':'local_container_check','cloudOperations':False,
213
+ 'boundary':'Exact immutable source in a cached Linux image, root-owned read-only inputs and nonroot check process, isolated loopback/network-none with no host mounts/socket/credentials. Check execution is not independent semantic or whole-system acceptance.'}
214
+
215
+ def recover(self, execution_id):
216
+ """Remove only this journaled validator container after supervisor loss.
217
+
218
+ A failed daemon query is uncertainty, not proof the prior work stopped.
219
+ Never replay a check as part of recovery.
220
+ """
221
+ name='atmem-validator-'+uuid.UUID(execution_id).hex
222
+ with tempfile.TemporaryDirectory(prefix='atmem-validator-recover-') as folder:
223
+ config=Path(folder)/'docker';config.mkdir();(config/'config.json').write_text('{}')
224
+ env={'PATH':os.environ.get('PATH',''),'HOME':folder,'DOCKER_CONFIG':str(config),'DOCKER_HOST':self.endpoint}
225
+ prefix=[self.binary,'--host',self.endpoint,'--config',str(config)]
226
+ def present():
227
+ result=subprocess.run([*prefix,'container','ls','-a','--filter',f'name=^/{name}$','--format','{{.Names}}'],env=env,capture_output=True,text=True,timeout=15)
228
+ if result.returncode:raise RuntimeError('Validator cleanup could not be confirmed')
229
+ names=result.stdout.splitlines()
230
+ if names not in ([],[name]):raise RuntimeError('Unexpected validator recovery result')
231
+ return bool(names)
232
+ if present():
233
+ result=subprocess.run([*prefix,'rm','-f',name],env=env,capture_output=True,timeout=15)
234
+ if result.returncode:raise RuntimeError('Validator cleanup could not be confirmed')
235
+ if present():raise RuntimeError('Validator cleanup could not be confirmed')
236
+ return {'cleanupConfirmed':True,'workReplayed':False}
@@ -0,0 +1,181 @@
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv pip compile --universal --python-version 3.13 server/memory-requirements.txt --generate-hashes --output-file server/memory-requirements.lock
3
+ atflows==0.1.4 \
4
+ --hash=sha256:2ada812488a9f22368975936fbafdcbe066a147bc88ae949213fef3724ce5261 \
5
+ --hash=sha256:d277f0aba85cbc82229cefd2aeb87b81548e4cd1f0276f2c8b4c758ecec4b36b
6
+ # via
7
+ # -r server/memory-requirements.txt
8
+ # atmem
9
+ atmem==2.3.10 \
10
+ --hash=sha256:e89f27ed6d9624cc4cb4e6d59286b48e53e430d2f2019737973488c3d43956cc \
11
+ --hash=sha256:f2e152ea2e710759fcb145cef34a33af5e173e0ef883aa2d75a5c01692a57c36
12
+ # via -r server/memory-requirements.txt
13
+ atmem-atbot==0.1.1 \
14
+ --hash=sha256:0b47efeda0ca46c4f3bcaa6ce4adabf7b5094841d788f3cfee783d668a6a03d1 \
15
+ --hash=sha256:9c6cd216dd23b79c712b21a7e671c78ad771b78a961489e1b3d183174a93771f
16
+ # via
17
+ # -r server/memory-requirements.txt
18
+ # atmem
19
+ cffi==2.1.1 \
20
+ --hash=sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e \
21
+ --hash=sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66 \
22
+ --hash=sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2 \
23
+ --hash=sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0 \
24
+ --hash=sha256:194cffa889098ced9976c3fc6340305e43f6303657d298da55366907c05c22d6 \
25
+ --hash=sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971 \
26
+ --hash=sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c \
27
+ --hash=sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d \
28
+ --hash=sha256:1dea0e4d7d4f11f619fe8c1d76caf49e24405b4b5743c0e3be16a500ecd930c9 \
29
+ --hash=sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517 \
30
+ --hash=sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735 \
31
+ --hash=sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80 \
32
+ --hash=sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f \
33
+ --hash=sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1 \
34
+ --hash=sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29 \
35
+ --hash=sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8 \
36
+ --hash=sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c \
37
+ --hash=sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e \
38
+ --hash=sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48 \
39
+ --hash=sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813 \
40
+ --hash=sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac \
41
+ --hash=sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632 \
42
+ --hash=sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6 \
43
+ --hash=sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1 \
44
+ --hash=sha256:3d22a20b1fb1632cc72c22f95f7b0d2961c3e1c235f245ba4c606c4771035659 \
45
+ --hash=sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688 \
46
+ --hash=sha256:42e2f76b9455f5a9a844f770bf3e200ed3da0e15f5df3db9c31fe80b04b3d004 \
47
+ --hash=sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0 \
48
+ --hash=sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062 \
49
+ --hash=sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779 \
50
+ --hash=sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94 \
51
+ --hash=sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50 \
52
+ --hash=sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab \
53
+ --hash=sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac \
54
+ --hash=sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6 \
55
+ --hash=sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676 \
56
+ --hash=sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1 \
57
+ --hash=sha256:5a59cc1c4442bc3d5c703bf720b51138d0bfc173618807c9ee2490a7541dd3d9 \
58
+ --hash=sha256:5bb4e7ea95dcd6a014a6fef62e62467d67d8e582326443f3d68e71d6320a9fcf \
59
+ --hash=sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13 \
60
+ --hash=sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e \
61
+ --hash=sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e \
62
+ --hash=sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973 \
63
+ --hash=sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527 \
64
+ --hash=sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72 \
65
+ --hash=sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890 \
66
+ --hash=sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c \
67
+ --hash=sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990 \
68
+ --hash=sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd \
69
+ --hash=sha256:75f80557d1389eddbd0de2681f6a390a0c5338c31ddaa821381c203fc3fd50d9 \
70
+ --hash=sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94 \
71
+ --hash=sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3 \
72
+ --hash=sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80 \
73
+ --hash=sha256:7ce713ace7c0e4520535b42b77eaa742c16dab813978064913e5a3cf82973b41 \
74
+ --hash=sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5 \
75
+ --hash=sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c \
76
+ --hash=sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a \
77
+ --hash=sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4 \
78
+ --hash=sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e \
79
+ --hash=sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6 \
80
+ --hash=sha256:9f8d177621de5cb38ee3e731eda45d421db093ec0739f46a5594babda7987a98 \
81
+ --hash=sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b \
82
+ --hash=sha256:a48d62ab9d6f4f98c983223a547af44be6ca3691074c31cecced6facd3ba2dc1 \
83
+ --hash=sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03 \
84
+ --hash=sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af \
85
+ --hash=sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231 \
86
+ --hash=sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2 \
87
+ --hash=sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3 \
88
+ --hash=sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836 \
89
+ --hash=sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5 \
90
+ --hash=sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399 \
91
+ --hash=sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96 \
92
+ --hash=sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e \
93
+ --hash=sha256:baed1e86cc735622097354b9d1281406caf42ff42a886d29faa8e8d1630333be \
94
+ --hash=sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf \
95
+ --hash=sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc \
96
+ --hash=sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455 \
97
+ --hash=sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0 \
98
+ --hash=sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12 \
99
+ --hash=sha256:ca82be1a1d406ecfe1d25dc16cb33488e5a16bf4438c9fb590484ea29d92478b \
100
+ --hash=sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7 \
101
+ --hash=sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692 \
102
+ --hash=sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54 \
103
+ --hash=sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3 \
104
+ --hash=sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b \
105
+ --hash=sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be \
106
+ --hash=sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d \
107
+ --hash=sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358 \
108
+ --hash=sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a \
109
+ --hash=sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7 \
110
+ --hash=sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc \
111
+ --hash=sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960 \
112
+ --hash=sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125 \
113
+ --hash=sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb \
114
+ --hash=sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a \
115
+ --hash=sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa \
116
+ --hash=sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf \
117
+ --hash=sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3 \
118
+ --hash=sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4 \
119
+ --hash=sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264
120
+ # via
121
+ # -r server/memory-requirements.txt
122
+ # cryptography
123
+ cryptography==48.0.1 \
124
+ --hash=sha256:08a597acce1ff37f347400087776599e2348a3a8bc53b44120e463cd274efe4a \
125
+ --hash=sha256:09f73a725d582cef64b91281a322cd798d14a33b2b6f2b7ad9531dc336d84c02 \
126
+ --hash=sha256:0df56b056bc17c1b7d6821dfa65216e62bd232d8ab05eb3db44e71d235651471 \
127
+ --hash=sha256:0ee6ea481db1ab889cba043ec1eda17bb9c1ea79db6722f779c3667f9f70322f \
128
+ --hash=sha256:15254441469dd6bf027039453288e2072124f8b6603563f5d759e1c9b69273fa \
129
+ --hash=sha256:266f4ee051abb2f725b74ef8072b521ce1feacf685a3364fa6a6b45548db791a \
130
+ --hash=sha256:2c37f2461406063b417837f5f3daab668652acd82423efcd7f0a9f04be972de1 \
131
+ --hash=sha256:32143b24adb918f078134e1e230f1eb8cc04886b92c28b5f0041aaf3e5699225 \
132
+ --hash=sha256:33842cf0888951cef5bc7ac724ab844a42044c1727b967b7f8997289a0464f92 \
133
+ --hash=sha256:3752f2dbc8f07a30aad2932c986cea495b03bb554887828225da104f732852b6 \
134
+ --hash=sha256:39489bfca54c7a1f6b297efcd8bc608ab92d16c4ca631b0cad4da46724588b24 \
135
+ --hash=sha256:3e4a1a3232eef2e6c732827d5722db29a0cc8b27af2a4d865b094cf954be9ca1 \
136
+ --hash=sha256:3fd2ca57062b241c856670b073487d2e86c4637937ca5601e48f97bf8e11fc8f \
137
+ --hash=sha256:42fcd8e26fe555d9b3577a135f5091fefa0aa4e99129c23fb56787a1bd4ada72 \
138
+ --hash=sha256:43c5835e2cb98c8733d86f57d6fc879b613f5c3478607281c3e36daffc6dd8a6 \
139
+ --hash=sha256:48fe40804d4caa2288f24e70ca8c64c42dd826da0ad7e4f1b41b2128d679e6c8 \
140
+ --hash=sha256:4ab0a343c807bbcd90c971cd1ecf072937cd01847a9e002bef88fb47ac6be577 \
141
+ --hash=sha256:4fdc69f8e4316bcf0c8c8ec1f26f285d12e8142d88d96c876a59a03be3f6ae67 \
142
+ --hash=sha256:6184ca7b174f28d7c703f1290d4b297217c45355f77a98f67e9b7f14549ac54a \
143
+ --hash=sha256:66fd0771e7b9c6dcd44cf1120690d2338d16d72795cf40cae2786a39eba65429 \
144
+ --hash=sha256:6b2c0c3e6ccf3ade7750f836ef3ee36eea250cc467d45c256895573ac08cc6f1 \
145
+ --hash=sha256:735824ec41b7f74a7c45fb1591349333e4c696cb6c044e5f46356e560143e4cd \
146
+ --hash=sha256:7e234ac052af99f2700826a5c29ea99d9c1b1f80341cde62d11c8154dc8e0bd9 \
147
+ --hash=sha256:869c3b8a53bfe27147832df48b32adadf558249d50e76cb3769d40e986b13265 \
148
+ --hash=sha256:86be3b1b0b6bf09482fb50a979c508d2950ed95f5621ec77f4e385962006b83a \
149
+ --hash=sha256:86fe77abb1bd87afb251d4d02ada7ecf53a32cee9b67d976abb2e45a13297475 \
150
+ --hash=sha256:88c852a0ae366e262e5a1744b685e6a433dc8788dd2a277e418bf4904203609d \
151
+ --hash=sha256:8ace4507d1e6533c125f4fac754f8bb8b6a74c08e92179dabd7e16571a3efbf3 \
152
+ --hash=sha256:92a46e1d638daa264ba2971c0b0489c9409787943efae4d60ffda3d091ef832c \
153
+ --hash=sha256:9621de99d2da096006b629979efd8ae7eb2d8b822488d0c89ee4000c306c59b1 \
154
+ --hash=sha256:9a49ca6c81417f6a5edb50375a60cccdd70fa0a91a5211829dbea74eba94d2ac \
155
+ --hash=sha256:9bd3f92d76217892b15df84ca256c2c113d386fdda7a7d8691aeeced976507c6 \
156
+ --hash=sha256:9de21387aa95e2a895823d0745b430bed4f33503ba9ab5e0b5311f33e37d66d2 \
157
+ --hash=sha256:b024e784ad6c077ee0147b35ea9cbfc1e34e1fd4c1dcca214c2794d73a12df08 \
158
+ --hash=sha256:b4e391975f038e66432328639620a4aff2d307513b004f1ca06d6225bced815c \
159
+ --hash=sha256:b74ca3b8e5ecdd833bf6a002ca41b4793bb27fb8f1c06ffaf2643c9e9140e31b \
160
+ --hash=sha256:b7a2d1a937a738a881737cec135a38bb61470589b17515b9f73f571d0ae10401 \
161
+ --hash=sha256:b9a32b876490d66c8bcc9963ef220199569748434ab01a9d6aaeabf88e7f5158 \
162
+ --hash=sha256:bd81490cd5801d755cf97bb68ac191f14b708470b1c7cf4580f669b9c9264cd8 \
163
+ --hash=sha256:c1400da5e32a43253392277eac7490a60e497d810a63dd5608d71bbd7af507c9 \
164
+ --hash=sha256:d069066deead00ac7f090be101be875a06855908f7ec004c27b8fefb4acfb411 \
165
+ --hash=sha256:d5d30989c6917b478b5817902e85fddaea2261efa8648383d965381ccb9e1ac4 \
166
+ --hash=sha256:df637c05205ea7c1d7fbcbe54bbfea648a52951155f997af13d895d0ecc96991 \
167
+ --hash=sha256:e361afba8918070d376df76f408a4f67fec0ee9cff81a99e48fe9a233ef59e17 \
168
+ --hash=sha256:eb86ce1af36fe65041b6db9a8bb064ee621a7e5fded0f80d475ec243477cd242 \
169
+ --hash=sha256:f0d27a5696721ef7a672b8c810f6aded391058e0b9486e63e6d93baf765da691 \
170
+ --hash=sha256:f2ceef93cb096aa3c4cc4b5c94ca6131f9196d28c64d6111533402a9b2054d41 \
171
+ --hash=sha256:f817adc181390bd54f2f700107a7419040fb7c1bdf2fc26f36551a06a68c3345 \
172
+ --hash=sha256:fe0180af5bf9236518a087e35bf2d9a347d5f5f51e63c579d683ddff424e3d46
173
+ # via
174
+ # -r server/memory-requirements.txt
175
+ # atmem
176
+ pycparser==3.12 \
177
+ --hash=sha256:a076f3f489b39b43ed13563a1dafe42447445bec2e294154ec5c57fcdda4c85e \
178
+ --hash=sha256:f03387877eab82ce01bbdfd0ba7252ee55a90b1c708d5129e2ce915475cf1db6
179
+ # via
180
+ # -r server/memory-requirements.txt
181
+ # cffi
@@ -0,0 +1,6 @@
1
+ atmem==2.3.10
2
+ atmem-atbot==0.1.1
3
+ atflows==0.1.4
4
+ cryptography==48.0.1
5
+ cffi==2.1.1
6
+ pycparser==3.12