@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,161 @@
1
+ """Owned Batch pool observation before source upload; never provisions a pool.
2
+
3
+ The contract is separate from the fourteen-field job/host policy to avoid a
4
+ bootstrap/hash cycle. Native installation, IAM/network resources and actual pool
5
+ image compatibility still need infrastructure/artifact and account evidence.
6
+ """
7
+ import copy
8
+ import hashlib
9
+ import json
10
+ import re
11
+ from enterprise_azure_jobs import configuration as job_configuration, fingerprint, typed_equal
12
+ from enterprise_sources import SourceUnavailable
13
+
14
+
15
+ def sha(value):
16
+ return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()).hexdigest()
17
+
18
+
19
+ def configuration(value, job):
20
+ job = job_configuration(job)
21
+ fields = {'format', 'identityResourceId', 'subnetId', 'vmSize', 'imageReference',
22
+ 'nodeAgentSkuId', 'startTaskSha256', 'dedicatedNodes', 'taskSlotsPerNode'}
23
+ if not isinstance(value, dict) or set(value) != fields or value['format'] != 'enterprise-azure-document-pool-v1':
24
+ raise ValueError('Use the exact owned Azure pool contract')
25
+ base = re.escape('/subscriptions/' + job['subscriptionId'] + '/resourceGroups/')
26
+ group = r'[A-Za-z0-9_().-]{1,90}'
27
+ name = r'[A-Za-z0-9_-]{1,80}'
28
+ patterns = {'identityResourceId': base + group + r'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/' + name,
29
+ 'subnetId': base + group + r'/providers/Microsoft.Network/virtualNetworks/' + name + '/subnets/' + name,
30
+ 'vmSize': r'Standard_[A-Za-z0-9_]{2,64}', 'startTaskSha256': r'[0-9a-f]{64}',
31
+ 'nodeAgentSkuId': r'batch\.node\.[a-z][a-z0-9 ._-]{1,64}'}
32
+ for key, pattern in patterns.items():
33
+ if not isinstance(value[key], str) or not re.fullmatch(pattern, value[key]):
34
+ raise ValueError('Invalid owned Azure pool placement or artifact contract')
35
+ image = value['imageReference']
36
+ if (not isinstance(image, dict) or set(image) != {'publisher', 'offer', 'sku', 'version'} or
37
+ not isinstance(image['publisher'], str) or not isinstance(image['offer'], str) or
38
+ (image['publisher'], image['offer']) not in {('microsoft-dsvm', 'ubuntu-hpc'), ('almalinux', '8-hpc-gen1'), ('almalinux', '8-hpc-gen2')} or
39
+ not isinstance(image['sku'], str) or not re.fullmatch('[a-zA-Z0-9_.-]{1,64}', image['sku']) or
40
+ not isinstance(image['version'], str) or not re.fullmatch(r'[0-9]{1,12}\.[0-9]{1,12}\.[0-9]{1,12}', image['version'])):
41
+ raise ValueError('Use a pinned reviewed container-compatible Linux image')
42
+ if (type(value['dedicatedNodes']) is not int or not 1 <= value['dedicatedNodes'] <= 100 or
43
+ type(value['taskSlotsPerNode']) is not int or not 1 <= value['taskSlotsPerNode'] <= 4):
44
+ raise ValueError('Use explicit bounded dedicated pool capacity')
45
+ return copy.deepcopy(value)
46
+
47
+
48
+ def metadata(value):
49
+ if not isinstance(value, list): raise ValueError('Native ownership metadata is required')
50
+ result = {}
51
+ for item in value:
52
+ if (not isinstance(item, dict) or set(item) != {'name', 'value'} or not isinstance(item['name'], str) or
53
+ not isinstance(item['value'], str) or item['name'] in result):
54
+ raise ValueError('Ambiguous native pool ownership metadata')
55
+ result[item['name']] = item['value']
56
+ return result
57
+
58
+
59
+ def image_matches(expected, observed):
60
+ if not isinstance(observed, dict): return False
61
+ allowed = set(expected) | {'exactVersion'}
62
+ return (not set(observed) - allowed and all(observed.get(k) == v for k, v in expected.items()) and
63
+ observed.get('exactVersion', expected['version']) == expected['version'])
64
+
65
+
66
+ def verify_start_task(value, contract, job):
67
+ fields = {'commandLine', 'resourceFiles', 'userIdentity', 'maxTaskRetryCount', 'waitForSuccess'}
68
+ if (not isinstance(value, dict) or set(value) != fields or value['waitForSuccess'] is not True or
69
+ type(value['maxTaskRetryCount']) is not int or value['maxTaskRetryCount'] != 0 or
70
+ value['userIdentity'] != {'autoUser': {'scope': 'pool', 'elevationLevel': 'admin'}} or
71
+ not isinstance(value['commandLine'], str) or len(value['commandLine'].encode()) > 32768 or
72
+ not value['commandLine'].startswith('/usr/bin/python3 -I -c ') or
73
+ not isinstance(value['resourceFiles'], list) or not 1 <= len(value['resourceFiles']) <= 3 or
74
+ sha(value) != contract['startTaskSha256']):
75
+ raise ValueError('Owned native installation task changed')
76
+ for resource in value['resourceFiles']:
77
+ if (not isinstance(resource, dict) or set(resource) != {'httpUrl', 'filePath', 'fileMode', 'identityReference'} or
78
+ resource['identityReference'] != {'resourceId': contract['identityResourceId']} or
79
+ resource['fileMode'] != '0400' or not isinstance(resource['filePath'], str) or
80
+ not re.fullmatch(r'[a-z][a-z0-9-]{0,63}\.zip', resource['filePath']) or
81
+ not isinstance(resource['httpUrl'], str) or not re.fullmatch(
82
+ re.escape('https://' + job['storageAccount'] + '.blob.core.windows.net/bootstrap/') + r'[0-9a-f]{64}\.zip', resource['httpUrl'])):
83
+ raise ValueError('Use only immutable owned-MI bootstrap packages')
84
+
85
+
86
+ def verify_pool(job, contract, observed):
87
+ if (not isinstance(observed, dict) or observed.get('id') != job['poolId'] or observed.get('state') != 'active' or
88
+ observed.get('allocationState') != 'steady'):
89
+ raise ValueError('Owned native pool is not active')
90
+ if metadata(observed.get('metadata')) != {'atmem-document-policy': fingerprint(job), 'atmem-start-task-sha256': contract['startTaskSha256']}:
91
+ raise ValueError('Owned native pool policy changed')
92
+ exact = {'enableAutoScale': False, 'enableInterNodeCommunication': False, 'targetLowPriorityNodes': 0,
93
+ 'currentLowPriorityNodes': 0, 'targetDedicatedNodes': contract['dedicatedNodes'],
94
+ 'currentDedicatedNodes': contract['dedicatedNodes'], 'taskSlotsPerNode': contract['taskSlotsPerNode']}
95
+ if any(not typed_equal(value, observed.get(key)) for key, value in exact.items()) or observed.get('vmSize') != contract['vmSize']:
96
+ raise ValueError('Owned native pool scheduling or capacity changed')
97
+ for field in ['applicationPackageReferences', 'userAccounts', 'mountConfiguration', 'resizeErrors']:
98
+ if observed.get(field) not in [None, []]: raise ValueError('Unexpected shared pool input or resize error')
99
+ native_identity = observed.get('identity')
100
+ if not isinstance(native_identity, dict) or set(native_identity) != {'type', 'userAssignedIdentities'} or native_identity['type'] != 'UserAssigned':
101
+ raise ValueError('Use only the dedicated transfer identity on the node')
102
+ identities = native_identity['userAssignedIdentities']
103
+ if not isinstance(identities, list) or len(identities) != 1: raise ValueError('Do not expose other workload identities to the node')
104
+ identity = identities[0]
105
+ if (not isinstance(identity, dict) or set(identity) != {'resourceId', 'clientId', 'principalId'} or
106
+ not isinstance(identity['resourceId'], str) or identity['resourceId'].lower() != contract['identityResourceId'].lower() or
107
+ identity['clientId'] != job['transferClientId'] or not isinstance(identity['principalId'], str) or
108
+ not re.fullmatch(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}', identity['principalId'])):
109
+ raise ValueError('Native pool managed identity changed')
110
+ network = observed.get('networkConfiguration')
111
+ if (not isinstance(network, dict) or not set(network) <= {'subnetId', 'publicIPAddressConfiguration', 'endpointConfiguration', 'enableAcceleratedNetworking'} or
112
+ network.get('subnetId', '').lower() != contract['subnetId'].lower() or
113
+ network.get('publicIPAddressConfiguration') != {'provision': 'nopublicipaddresses'} or
114
+ network.get('endpointConfiguration') not in [None, {'inboundNATPools': []}]):
115
+ raise ValueError('Use the exact same-subscription private subnet without public endpoints')
116
+ machine = observed.get('virtualMachineConfiguration')
117
+ if (not isinstance(machine, dict) or set(machine) != {'imageReference', 'nodeAgentSKUId', 'containerConfiguration', 'diskEncryptionConfiguration'} or
118
+ not image_matches(contract['imageReference'], machine['imageReference']) or machine['nodeAgentSKUId'] != contract['nodeAgentSkuId'] or
119
+ machine['diskEncryptionConfiguration'] != {'targets': ['osdisk', 'temporarydisk']}):
120
+ raise ValueError('Owned native image, agent SKU or disk encryption changed')
121
+ registry = job['parserImage'].split('/')[0]
122
+ expected = {'type': 'dockerCompatible', 'containerImageNames': [job['parserImage'], job['transferImage']],
123
+ 'containerRegistries': [{'registryServer': registry, 'identityReference': {'resourceId': contract['identityResourceId']}}]}
124
+ if not typed_equal(expected, machine['containerConfiguration']):
125
+ raise ValueError('Use only the prefetched immutable images and dedicated registry identity')
126
+ verify_start_task(observed.get('startTask'), contract, job)
127
+ return True
128
+
129
+
130
+ def verify_nodes(job, contract, response):
131
+ if (not isinstance(response, dict) or response.get('odata.nextLink') or response.get('@odata.nextLink') or
132
+ not isinstance(response.get('value'), list) or len(response['value']) != contract['dedicatedNodes']):
133
+ raise ValueError('Observe every node in the explicit dedicated pool')
134
+ identifiers = set()
135
+ for node in response['value']:
136
+ if (not isinstance(node, dict) or not isinstance(node.get('id'), str) or not re.fullmatch('[A-Za-z0-9_-]{1,128}', node['id']) or
137
+ node['id'] in identifiers or node.get('state') not in {'idle', 'running'} or node.get('schedulingState') != 'enabled' or
138
+ node.get('isDedicated') is not True or node.get('publicIPAddress') or node.get('publicIPv6Address') or node.get('errors') or
139
+ node.get('vmSize') != contract['vmSize']):
140
+ raise ValueError('Native dedicated node is not ready or private')
141
+ version = node.get('nodeAgentInfo', {}).get('version')
142
+ if not isinstance(version, str) or not re.fullmatch(r'[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}', version) or tuple(map(int, version.split('.'))) <= (1, 11, 11):
143
+ raise ValueError('Native node agent must support explicit empty container mounts')
144
+ startup = node.get('startTaskInfo', {})
145
+ if (startup.get('state') != 'completed' or type(startup.get('exitCode')) is not int or startup['exitCode'] != 0 or
146
+ startup.get('result') != 'success' or startup.get('failureInfo') or
147
+ not image_matches(contract['imageReference'], node.get('virtualMachineInfo', {}).get('imageReference'))):
148
+ raise ValueError('Native node did not complete the pinned installation on the pinned image')
149
+ verify_start_task(node.get('startTask'), contract, job)
150
+ identifiers.add(node['id'])
151
+ return frozenset(identifiers)
152
+
153
+
154
+ def preflight(job, contract, api):
155
+ job = job_configuration(job); contract = configuration(contract, job)
156
+ try:
157
+ api.account()
158
+ verify_pool(job, contract, api.pool())
159
+ return verify_nodes(job, contract, api.nodes())
160
+ except Exception:
161
+ raise SourceUnavailable('document_batch_pool_unavailable') from None
@@ -0,0 +1,122 @@
1
+ """Trusted Azure transfer stages; the untrusted parser never runs in this image."""
2
+ import json
3
+ import os
4
+ from pathlib import Path
5
+ import re
6
+ import sys
7
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
8
+ from enterprise_azure_objects import AzureDocumentObjects, etag
9
+ from enterprise_document_contract import MAX_INPUT, MEDIA_TYPES, media_type
10
+ from enterprise_document_job import MAX_ENVELOPE, read_file, request, result, unique
11
+ from enterprise_sources import SourceUnavailable
12
+
13
+
14
+ def metadata(encoded):
15
+ if not isinstance(encoded, str) or not 0 < len(encoded.encode()) <= 4096:
16
+ raise ValueError('Use bounded owned transfer metadata')
17
+ value = json.loads(encoded, object_pairs_hook=unique)
18
+ fields = {'format', 'subscriptionId', 'region', 'resourceGroup', 'storageAccount',
19
+ 'container', 'transferClientId', 'request', 'inputETag'}
20
+ if not isinstance(value, dict) or set(value) != fields or value['format'] != 'enterprise-azure-document-transfer-v1':
21
+ raise ValueError('Use the exact Azure document transfer metadata')
22
+ # Constructing the native destination validates every identifier without
23
+ # acquiring a token or making an HTTP call. Close the unstarted session.
24
+ objects = document_objects(value)
25
+ objects.close()
26
+ expected = value['request']
27
+ if (not isinstance(expected, dict) or set(expected) != {'format', 'requestId', 'sha256', 'mediaType'} or
28
+ expected['format'] != 'enterprise-document-job-v1' or
29
+ not isinstance(expected['requestId'], str) or not re.fullmatch('[0-9a-f]{64}', expected['requestId']) or
30
+ not isinstance(expected['sha256'], str) or not re.fullmatch('[0-9a-f]{64}', expected['sha256']) or
31
+ media_type(expected['mediaType']) != expected['mediaType'] or
32
+ expected['mediaType'] not in MEDIA_TYPES | {'application/octet-stream'}):
33
+ raise ValueError('Use the exact supported byte-bound request')
34
+ try: etag(value['inputETag'])
35
+ except SourceUnavailable: raise ValueError('Use the acknowledged native input ETag') from None
36
+ return value
37
+
38
+
39
+ def document_objects(value):
40
+ return AzureDocumentObjects(subscription=value['subscriptionId'], resource_group=value['resourceGroup'],
41
+ region=value['region'], account=value['storageAccount'], container=value['container'], client_id=value['transferClientId'])
42
+
43
+
44
+ def directories(input_path, output_path):
45
+ source = target = None
46
+ try:
47
+ source = os.open(input_path, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
48
+ target = os.open(output_path, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
49
+ left, right = os.fstat(source), os.fstat(target)
50
+ if (left.st_dev, left.st_ino) == (right.st_dev, right.st_ino):
51
+ raise ValueError('Use distinct per-file volumes')
52
+ return source, target
53
+ except BaseException:
54
+ for fd in [target, source]:
55
+ if fd is not None: os.close(fd)
56
+ raise
57
+
58
+
59
+ def download(value, objects, input_path='/input', output_path='/output'):
60
+ source, target = directories(input_path, output_path)
61
+ try:
62
+ if os.listdir(source) or os.listdir(target):
63
+ raise ValueError('Use fresh per-file volumes')
64
+ expected = value['request']
65
+ identifier = expected['requestId']
66
+ raw = objects.load(identifier, 'input', value['inputETag'])
67
+ if request(raw, expected['mediaType'], identifier) != expected:
68
+ raise ValueError('Input bytes changed')
69
+ for name, data in [('document', raw), ('request.json', json.dumps(expected, separators=(',', ':')).encode())]:
70
+ fd = os.open(name, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o444, dir_fd=source)
71
+ with os.fdopen(fd, 'wb') as stream:
72
+ stream.write(data)
73
+ stream.flush()
74
+ os.fsync(stream.fileno())
75
+ os.fchmod(stream.fileno(), 0o444)
76
+ # Batch maps a native non-admin UID. Fresh isolated output is writable
77
+ # by that UID; only its parser and the trusted collector receive mounts.
78
+ os.fchmod(source, 0o555)
79
+ os.fchmod(target, 0o777)
80
+ os.fsync(source)
81
+ os.fsync(target)
82
+ finally:
83
+ os.close(target)
84
+ os.close(source)
85
+
86
+
87
+ def upload(value, objects, input_path='/input', output_path='/output'):
88
+ source, target = directories(input_path, output_path)
89
+ try:
90
+ expected = value['request']
91
+ identifier = expected['requestId']
92
+ raw = read_file(source, 'document', MAX_INPUT)
93
+ if request(raw, expected['mediaType'], identifier) != expected:
94
+ raise ValueError('Input binding changed')
95
+ encoded = read_file(target, 'result.json', MAX_ENVELOPE)
96
+ result(raw, expected['mediaType'], identifier, encoded)
97
+ objects.put(identifier, 'result', encoded)
98
+ finally:
99
+ os.close(target)
100
+ os.close(source)
101
+
102
+
103
+ def main():
104
+ objects = None
105
+ try:
106
+ if len(sys.argv) != 2 or sys.argv[1] not in {'download', 'upload'}:
107
+ raise ValueError('Use the fixed Azure transfer stage')
108
+ value = metadata(os.environ.get('DOCUMENT_JOB', ''))
109
+ objects = document_objects(value)
110
+ if sys.argv[1] == 'download': download(value, objects)
111
+ else: upload(value, objects)
112
+ except Exception:
113
+ raise SystemExit('Owned Azure document transfer could not complete.') from None
114
+ finally:
115
+ if objects is not None:
116
+ try: objects.close()
117
+ except Exception:
118
+ raise SystemExit('Owned Azure document transfer could not complete.') from None
119
+
120
+
121
+ if __name__ == '__main__':
122
+ main()
@@ -0,0 +1,136 @@
1
+ """Owned private deployment metadata and native SQL identity dispatch.
2
+
3
+ No connection, cloud request, user enrollment or schema mutation occurs on import.
4
+ Metadata is packaged by the compiler/operator, never read from a chat request.
5
+ """
6
+ import hashlib
7
+ import json
8
+ import os
9
+ from pathlib import Path
10
+ import re
11
+ from urllib.parse import urlsplit
12
+ from enterprise_identity import CompanyIdentity, trusted_https
13
+ from enterprise_sources import GraphSharePoint, ConfluenceCloud
14
+ from public_faq import object_pairs
15
+
16
+
17
+ def deployment(value):
18
+ if (not isinstance(value, dict) or set(value) != {'format', 'provider', 'accountId', 'publicOrigin', 'company', 'sources', 'parserRevision'}
19
+ or value['format'] != 'enterprise-knowledge-v1' or value['provider'] not in {'aws', 'azure', 'gcp', 'ibm'}
20
+ or not isinstance(value['accountId'], str) or not re.fullmatch(r'[A-Za-z0-9_-]{1,128}', value['accountId'])
21
+ or not isinstance(value['parserRevision'], str) or not re.fullmatch(r'[0-9a-f]{64}', value['parserRevision'])):
22
+ raise ValueError('Invalid owned private deployment metadata')
23
+ origin = trusted_https(value['publicOrigin'])
24
+ if urlsplit(origin).path or origin.endswith('/'):
25
+ raise ValueError('Use the canonical owned HTTPS origin')
26
+ company = value['company']
27
+ if not isinstance(company, dict) or set(company) != {'issuer', 'audience', 'jwksUri', 'scope', 'web'}:
28
+ raise ValueError('Supply the existing company API and public OIDC registration')
29
+ identity = CompanyIdentity(value['accountId'], company['issuer'], company['audience'], company['jwksUri'], company['scope'])
30
+ from enterprise_web import company_configuration
31
+ company_configuration(identity, company['web'])
32
+ sources = value['sources']
33
+ if not isinstance(sources, dict) or set(sources) != {'sharepoint', 'confluence'}:
34
+ raise ValueError('Supply the existing SharePoint and Confluence registrations')
35
+ graph, confluence = sources['sharepoint'], sources['confluence']
36
+ if not isinstance(graph, dict) or set(graph) != {'tenantId', 'clientId', 'driveId', 'host'}:
37
+ raise ValueError('Invalid owned Graph registration')
38
+ if any(not isinstance(graph[key], str) or not re.fullmatch(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', graph[key]) for key in ['tenantId', 'clientId']):
39
+ raise ValueError('Use the owned Graph tenant and confidential client IDs')
40
+ if (not isinstance(confluence, dict) or set(confluence) != {'clientId', 'cloudId', 'host', 'spaces'}
41
+ or not isinstance(confluence['clientId'], str) or not re.fullmatch(r'[A-Za-z0-9_-]{1,200}', confluence['clientId'])):
42
+ raise ValueError('Invalid owned Confluence registration')
43
+ # Constructor validation is local only: no delegated access is used here.
44
+ GraphSharePoint(graph['driveId'], graph['host'], None)
45
+ ConfluenceCloud(confluence['cloudId'], confluence['host'], confluence['spaces'], None)
46
+ return json.loads(json.dumps(value, allow_nan=False))
47
+
48
+
49
+ def read_owned_json(filename,direct,pointer,environment,*,path=None):
50
+ """Compiler/operator metadata only; no chat/request chooses a file or loader."""
51
+ if (direct in environment and pointer in environment)or(path is not None and any(key in environment for key in [direct,pointer])):
52
+ raise ValueError('Conflicting owned configuration sources')
53
+ if direct in environment:
54
+ value=environment[direct]
55
+ if not isinstance(value,str):raise ValueError('Use serialized owned configuration')
56
+ raw=value.encode('utf-8')
57
+ else:
58
+ if pointer in environment:
59
+ value=environment[pointer]
60
+ if not isinstance(value,str)or not Path(value).is_absolute():raise ValueError('Use an absolute owned configuration mount')
61
+ path=Path(value)
62
+ path=Path(path)if path is not None else Path(__file__).with_name(filename)
63
+ with path.open('rb')as stream:raw=stream.read(32769)
64
+ if not 0<len(raw)<=32768:raise ValueError('Owned configuration exceeds its byte boundary')
65
+ def constant(value):raise ValueError('Use finite owned JSON values')
66
+ return json.loads(raw,object_pairs_hook=object_pairs,parse_constant=constant)
67
+
68
+
69
+ def read_deployment(path=None,*,environment=None):
70
+ environment=os.environ if environment is None else environment
71
+ return deployment(read_owned_json('enterprise-deployment.json','ENTERPRISE_DEPLOYMENT_JSON','ENTERPRISE_DEPLOYMENT_FILE',environment,path=path))
72
+
73
+
74
+ def session_domain(metadata):
75
+ return hashlib.sha256(json.dumps({'account':metadata['accountId'],'origin':metadata['publicOrigin'],
76
+ 'company':metadata['company'],'sources':metadata['sources'],'provider':metadata['provider']},sort_keys=True,separators=(',',':')).encode()).hexdigest()
77
+
78
+
79
+ def native_database(provider, environment, role, secrets):
80
+ from workflow_connection import aws_database, azure_database, gcp_database, ibm_database
81
+ if role not in {'api', 'worker', 'migration'}:
82
+ raise ValueError('Use the owned native database role')
83
+ env = environment
84
+ common = {'database': env['DATABASE_NAME'], 'role': role}
85
+ if provider == 'gcp':
86
+ transport = env.get('DATABASE_TRANSPORT', 'cloudsql-socket')
87
+ if transport not in {'cloudsql-socket', 'cloudsql-private-proxy'}:
88
+ raise ValueError('Use the owned Cloud SQL transport')
89
+ return gcp_database(**common, connection_name=env['DATABASE_CONNECTION_NAME'],
90
+ service_account_email=env['DATABASE_SERVICE_ACCOUNT'], private_proxy=transport == 'cloudsql-private-proxy')
91
+ common.update(host=env['DATABASE_HOST'], user=env['DATABASE_USER'], ca_file=secrets.env['DATABASE_CA_FILE'])
92
+ if provider == 'aws': return aws_database(**common, region=env['REGION'])
93
+ if provider == 'azure': return azure_database(**common, managed_identity_client_id=env['WORKLOAD_IDENTITY_CLIENT_ID'])
94
+ if provider == 'ibm': return ibm_database(**common, port=int(env['DATABASE_PORT']), password=secrets.reader('database_password'))
95
+ raise ValueError('Unsupported owned database provider')
96
+
97
+
98
+ def validate_runtime(auth, role, account_id):
99
+ if role not in {'api', 'worker'}: raise ValueError('Use a runtime database identity')
100
+ schemas = {'enterprise_auth': 'enterprise_auth_schema.sql', 'enterprise_queries': 'enterprise_queries_schema.sql',
101
+ 'enterprise_audit': 'enterprise_audit_schema.sql'}
102
+ if role == 'worker':
103
+ schemas['enterprise_extractions'] = 'enterprise_extraction_schema.sql'
104
+ schemas['enterprise_document_jobs'] = 'enterprise_document_jobs_schema.sql'
105
+ with auth.transaction() as cursor:
106
+ row = cursor.execute('SELECT rolsuper,rolcreatedb,rolcreaterole,rolreplication,rolbypassrls FROM pg_roles WHERE rolname=current_user').fetchone()
107
+ if not row or any(row.values()): raise ValueError('Private runtime must use its nonadministrative database identity')
108
+ for schema, filename in schemas.items():
109
+ if cursor.execute('SELECT has_schema_privilege(current_user,%s,\'CREATE\') AS allowed', (schema,)).fetchone()['allowed']:
110
+ raise ValueError('Runtime must not own private application schemas')
111
+ # Identifiers come only from the fixed dictionary above.
112
+ current = cursor.execute('SELECT version,source_sha256 FROM ' + schema + '.schema_version').fetchone()
113
+ expected = hashlib.sha256(Path(__file__).with_name(filename).read_bytes()).hexdigest()
114
+ if current != {'version': 1, 'source_sha256': expected}:
115
+ raise ValueError('Private runtime schema differs; run the reviewed operator lifecycle')
116
+ queue = cursor.execute('SELECT queue_version FROM enterprise_queries.schema_version').fetchone()
117
+ if queue['queue_version'] != '3.10.0': raise ValueError('Private runtime queue version differs')
118
+ for table in ['enterprise_auth.memberships', 'enterprise_auth.source_mappings', 'enterprise_auth.company_bindings', 'enterprise_auth.schema_version']:
119
+ if cursor.execute('SELECT has_table_privilege(current_user,%s,\'INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER,REFERENCES\') AS allowed', (table,)).fetchone()['allowed']:
120
+ raise ValueError('Runtime must not inherit company authority writes')
121
+ if cursor.execute("SELECT has_table_privilege(current_user,'enterprise_audit.events','SELECT,UPDATE,DELETE,TRUNCATE,TRIGGER,REFERENCES') AS allowed").fetchone()['allowed']:
122
+ raise ValueError('Runtime must use append-only audit authority')
123
+ if cursor.execute("SELECT has_table_privilege(current_user,'enterprise_auth.administration_events','SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER,REFERENCES') AS allowed").fetchone()['allowed']:
124
+ raise ValueError('Runtime must not inherit operator history authority')
125
+ if role == 'api' and cursor.execute("SELECT has_table_privilege(current_user,'enterprise_queries.procrastinate_jobs','UPDATE,DELETE,TRUNCATE') AS allowed").fetchone()['allowed']:
126
+ raise ValueError('API must not inherit worker queue mutation authority')
127
+ forbidden = 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,TRIGGER,REFERENCES' if role == 'api' else 'TRUNCATE,TRIGGER,REFERENCES'
128
+ table = cursor.execute("SELECT c.oid::bigint AS oid FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE n.nspname='enterprise_document_jobs'AND c.relname='jobs'AND c.relkind='r'").fetchone()
129
+ if not table:raise ValueError('Private document cleanup schema is missing')
130
+ # API deliberately has no schema USAGE. Resolve the object through the
131
+ # public system catalogue instead of broadening its application grants.
132
+ if cursor.execute("SELECT has_table_privilege(current_user,%s::oid,%s) AS allowed", (table['oid'],forbidden)).fetchone()['allowed']:
133
+ raise ValueError('Use only the owned worker cleanup metadata authority')
134
+ from enterprise_sources import SourceDenied
135
+ try:auth.require_company(cursor,account_id)
136
+ except SourceDenied:raise ValueError('Activate the owned company registration with the reviewed operator lifecycle')from None
@@ -0,0 +1,116 @@
1
+ """General company-document decoding in a separate credentialless parser service.
2
+
3
+ This module accepts bytes, never caller-selected URLs or parser configuration.
4
+ The JVM/native tools must be contained by the deployment's network/resource sandbox;
5
+ process deadlines alone are not isolation. Invoice PDF protocol is unchanged.
6
+ """
7
+ import base64
8
+ import hashlib
9
+ import os
10
+ from pathlib import Path
11
+ import selectors
12
+ import signal
13
+ import subprocess
14
+ import tempfile
15
+ import time
16
+
17
+ from enterprise_document_contract import MAX_INPUT, MAX_TEXT, MEDIA_TYPES, ExtractionError, media_type, document_result
18
+
19
+
20
+ class CompanyDocument:
21
+ def __init__(self, *, java, classpath, pdf, timeout=30):
22
+ if not Path(java).is_absolute() or not Path(java).is_file():
23
+ raise ValueError('Supply the installed pinned Java executable')
24
+ if not isinstance(classpath, (list, tuple)) or not classpath or any(not Path(p).is_absolute() or not Path(p).exists() for p in classpath):
25
+ raise ValueError('Supply the fixed bridge and verified Tika classpath')
26
+ if not callable(getattr(pdf, 'extract', None)) or type(timeout) is not int or not 1 <= timeout <= 110:
27
+ raise ValueError('Supply the bounded native PDF extractor and timeout')
28
+ self.java = java
29
+ self.classpath = os.pathsep.join(str(p) for p in classpath)
30
+ self.pdf = pdf
31
+ self.timeout = timeout
32
+
33
+ def extract(self, raw, declared):
34
+ if not isinstance(raw, bytes) or not raw:
35
+ raise ExtractionError('invalid_document')
36
+ if len(raw) > MAX_INPUT:
37
+ raise ExtractionError('document_too_large')
38
+ declared = media_type(declared)
39
+ digest = hashlib.sha256(raw).hexdigest()
40
+ if raw.startswith(b'%PDF-'):
41
+ from invoice_document import DocumentError
42
+ try:
43
+ parsed = self.pdf.extract(raw, digest)
44
+ except DocumentError as failure:
45
+ raise ExtractionError('extraction_timeout' if failure.code == 'extraction_timeout' else 'extraction_failed') from None
46
+ pages = []
47
+ for page in parsed['pages']:
48
+ native, ocr = page['text'].strip(), page['ocr'].strip()
49
+ # Both channels matter for mixed text/image pages. Do not discard
50
+ # image-only facts because a page also has a native-text header.
51
+ body = native if native == ocr else '\n'.join(part for part in (native, ocr) if part)
52
+ pages.append(f"Page {page['number']}\n{body}")
53
+ detected, text = 'application/pdf', '\n\n'.join(pages)
54
+ else:
55
+ detected, text = self._tika(raw)
56
+ return document_result({'format': 'enterprise-document-v1', 'sha256': digest,
57
+ 'mediaType': detected, 'text': text}, raw, declared)
58
+
59
+ def _tika(self, raw):
60
+ with tempfile.TemporaryDirectory(prefix='atmem-company-document-') as temporary:
61
+ folder = Path(temporary)
62
+ source = folder / 'input'
63
+ source.write_bytes(raw)
64
+ source.chmod(0o600)
65
+ process = None
66
+ try:
67
+ # No JAVA_TOOL_OPTIONS, CLASSPATH, proxy, application or workload
68
+ # credentials enter the parser. Child tools share the outer group.
69
+ process = subprocess.Popen([self.java, '-Xmx256m', '-XX:ActiveProcessorCount=1',
70
+ '-Djava.awt.headless=true', '-Djava.io.tmpdir=' + temporary,
71
+ '-cp', self.classpath, 'EnterpriseDocument', str(source)],
72
+ stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
73
+ cwd=folder, start_new_session=True, env={'PATH': '/usr/local/bin:/usr/bin:/bin', 'HOME': temporary,
74
+ 'TMPDIR': temporary, 'LANG': 'C.UTF-8', 'OMP_THREAD_LIMIT': '1',
75
+ 'TESSDATA_PREFIX': '/usr/share/tesseract-ocr/5/tessdata'})
76
+ deadline = time.monotonic() + self.timeout
77
+ output = bytearray()
78
+ with selectors.DefaultSelector() as selector:
79
+ os.set_blocking(process.stdout.fileno(), False)
80
+ selector.register(process.stdout, selectors.EVENT_READ)
81
+ while selector.get_map():
82
+ remaining = deadline - time.monotonic()
83
+ if remaining <= 0:
84
+ raise ExtractionError('extraction_timeout')
85
+ for key, _ in selector.select(min(remaining, .1)):
86
+ chunk = os.read(key.fd, 8192)
87
+ if not chunk:
88
+ selector.unregister(key.fileobj)
89
+ else:
90
+ output.extend(chunk)
91
+ if len(output) > 270000:
92
+ raise ExtractionError('extraction_failed')
93
+ try:
94
+ code = process.wait(timeout=max(.01, deadline - time.monotonic()))
95
+ except subprocess.TimeoutExpired:
96
+ raise ExtractionError('extraction_timeout') from None
97
+ lines = output.decode('ascii').splitlines()
98
+ if code == 2 and lines == ['rejected', 'unsupported_format']:
99
+ raise ExtractionError('unsupported_format')
100
+ if code != 0 or len(lines) != 3 or lines[0] != 'ok':
101
+ raise ExtractionError('extraction_failed')
102
+ return lines[1], base64.b64decode(lines[2], validate=True).decode('utf-8')
103
+ except ExtractionError:
104
+ raise
105
+ except Exception:
106
+ raise ExtractionError('extraction_unavailable') from None
107
+ finally:
108
+ if process is not None:
109
+ # Kill the entire private group, including an OCR child that
110
+ # outlived a failed/crashed JVM. Never leave document workers.
111
+ try:
112
+ os.killpg(process.pid, signal.SIGKILL)
113
+ except ProcessLookupError:
114
+ pass
115
+ process.wait()
116
+ process.stdout.close()
@@ -0,0 +1,32 @@
1
+ """Byte-only CLI used by the isolated document parser image."""
2
+ import json
3
+ from pathlib import Path
4
+ import sys
5
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
6
+ from enterprise_document import CompanyDocument, ExtractionError, MAX_INPUT
7
+ from invoice_document import PdfDocument
8
+
9
+
10
+ def installed_parser():
11
+ return CompanyDocument(java='/opt/java/bin/java',
12
+ classpath=['/app/tika-app.jar', '/app/document-bridge'], pdf=PdfDocument())
13
+
14
+
15
+ if __name__ == '__main__':
16
+ if sys.argv[1:] == ['--job']:
17
+ from enterprise_document_job import execute
18
+ value, code = execute(installed_parser())
19
+ print(json.dumps(value, allow_nan=False))
20
+ raise SystemExit(code)
21
+ try:
22
+ if len(sys.argv) > 2:
23
+ raise ExtractionError('invalid_document')
24
+ raw = sys.stdin.buffer.read(MAX_INPUT + 1)
25
+ document = installed_parser().extract(raw, sys.argv[1] if len(sys.argv) == 2 else 'application/octet-stream')
26
+ value, code = {'status': 'ok', 'document': document}, 0
27
+ except ExtractionError as failure:
28
+ value, code = {'status': 'rejected', 'reason': failure.code}, 2
29
+ except Exception:
30
+ value, code = {'status': 'rejected', 'reason': 'extraction_unavailable'}, 2
31
+ print(json.dumps(value, ensure_ascii=False, allow_nan=False))
32
+ raise SystemExit(code)
@@ -0,0 +1,54 @@
1
+ """Byte-bound document protocol shared by app/cache and isolated parser.
2
+
3
+ Standard-library validation only: no subprocess, native parser, URL or secrets.
4
+ """
5
+ import hashlib
6
+ import re
7
+
8
+ MAX_INPUT = 10000000
9
+ MAX_TEXT = 200000
10
+ MEDIA_TYPES = frozenset({'application/pdf', 'text/plain', 'text/html', 'application/rtf',
11
+ 'application/msword', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint',
12
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
13
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
14
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
15
+ 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.spreadsheet',
16
+ 'application/vnd.oasis.opendocument.presentation'})
17
+
18
+
19
+ class ExtractionError(ValueError):
20
+ def __init__(self, code):
21
+ if code not in {'document_too_large', 'invalid_document', 'unsupported_format',
22
+ 'extraction_failed', 'extraction_timeout', 'extraction_unavailable', 'mime_mismatch'}:
23
+ raise ValueError('Unknown extraction failure')
24
+ self.code = code
25
+ super().__init__(code)
26
+
27
+
28
+ def media_type(value):
29
+ if not isinstance(value, str) or len(value) > 200 or any(ord(c) < 32 for c in value):
30
+ raise ExtractionError('invalid_document')
31
+ result = value.split(';', 1)[0].strip().lower()
32
+ if not re.fullmatch(r'[a-z0-9.+-]+/[a-z0-9.+-]+', result):
33
+ raise ExtractionError('invalid_document')
34
+ return {'text/rtf': 'application/rtf', 'application/x-rtf': 'application/rtf'}.get(result, result)
35
+
36
+
37
+ def document_result(value, raw, declared):
38
+ """Validate the entire byte-bound response at both sides of the RPC boundary."""
39
+ if not isinstance(raw, bytes) or not 0 < len(raw) <= MAX_INPUT:
40
+ raise ExtractionError('invalid_document')
41
+ if not isinstance(value, dict) or set(value) != {'format', 'sha256', 'mediaType', 'text'}:
42
+ raise ExtractionError('invalid_document')
43
+ if value['format'] != 'enterprise-document-v1' or value['sha256'] != hashlib.sha256(raw).hexdigest():
44
+ raise ExtractionError('invalid_document')
45
+ actual = media_type(value['mediaType'])
46
+ if actual not in MEDIA_TYPES or actual != value['mediaType']:
47
+ raise ExtractionError('unsupported_format')
48
+ expected = media_type(declared)
49
+ if actual != expected and expected != 'application/octet-stream':
50
+ raise ExtractionError('mime_mismatch')
51
+ text = value['text']
52
+ if not isinstance(text, str) or not text.strip() or len(text.encode('utf-8')) > MAX_TEXT or '\x00' in text:
53
+ raise ExtractionError('invalid_document')
54
+ return value