@atmem/architect 0.0.0-stage → 0.2.0-alpha.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/CONSTITUTION.md +144 -0
  2. package/README.md +33 -2
  3. package/agent-skills/discovery/SKILL.md +48 -0
  4. package/agent-skills/discovery/topics.json +139 -0
  5. package/agent-skills/generation-capabilities.json +760 -0
  6. package/agent-skills/service-lifecycle.json +21 -0
  7. package/agent-skills/specialists/architecture/SKILL.md +15 -0
  8. package/agent-skills/specialists/aws/SKILL.md +17 -0
  9. package/agent-skills/specialists/azure/SKILL.md +7 -0
  10. package/agent-skills/specialists/composition/SKILL.md +17 -0
  11. package/agent-skills/specialists/devops/SKILL.md +10 -0
  12. package/agent-skills/specialists/finops/SKILL.md +7 -0
  13. package/agent-skills/specialists/gcp/SKILL.md +7 -0
  14. package/agent-skills/specialists/ibm/SKILL.md +7 -0
  15. package/agent-skills/specialists/manifest.json +13 -0
  16. package/agent-skills/specialists/pulumi/SKILL.md +7 -0
  17. package/agent-skills/specialists/security/SKILL.md +7 -0
  18. package/agent-skills/specialists/terraform/SKILL.md +14 -0
  19. package/agent-skills/upstream/aws/LICENSE +175 -0
  20. package/agent-skills/upstream/aws/SKILL.md +125 -0
  21. package/agent-skills/upstream/azure/LICENSE +21 -0
  22. package/agent-skills/upstream/azure/SKILL.md +387 -0
  23. package/agent-skills/upstream/gcp/LICENSE +202 -0
  24. package/agent-skills/upstream/gcp/SKILL.md +159 -0
  25. package/agent-skills/upstream/manifest.json +57 -0
  26. package/agent-skills/upstream/pulumi/LICENSE +201 -0
  27. package/agent-skills/upstream/pulumi/SKILL.md +501 -0
  28. package/agent-skills/upstream/terraform/LICENSE +373 -0
  29. package/agent-skills/upstream/terraform/SKILL.md +316 -0
  30. package/agent-skills/workflows/workflows.json +601 -0
  31. package/cli/architect.mjs +3 -0
  32. package/cli/runtime.mjs +115 -0
  33. package/dist/assets/html2canvas.esm-QH1iLAAe.js +22 -0
  34. package/dist/assets/index-B97MkVMs.css +1 -0
  35. package/dist/assets/index-qtCM2D7O.js +21271 -0
  36. package/dist/assets/index.es-C6C0sneB.js +18 -0
  37. package/dist/assets/purify.es-CAi2OJFm.js +3 -0
  38. package/dist/assets/visual-export-DjbjgQbA.js +173 -0
  39. package/dist/favicon.svg +2 -0
  40. package/dist/fonts/DM-Sans-OFL.txt +93 -0
  41. package/dist/fonts/Manrope-OFL.txt +93 -0
  42. package/dist/fonts/NotoSans-Regular.ttf +0 -0
  43. package/dist/fonts/OFL.txt +94 -0
  44. package/dist/fonts/dm-sans-latin-wght-normal.woff2 +0 -0
  45. package/dist/fonts/manrope-latin-wght-normal.woff2 +0 -0
  46. package/dist/index.html +4 -0
  47. package/dist/licenses/aws-architect-LICENSE.txt +17 -0
  48. package/dist/licenses/aws-mcp-LICENSE.txt +175 -0
  49. package/dist/licenses/aws-mcp-NOTICE.txt +1 -0
  50. package/dist/licenses/cloud-emulation-notices.txt +36619 -0
  51. package/dist/licenses/dependency-notices.txt +6379 -0
  52. package/dist/licenses/emulation-notices.txt +717 -0
  53. package/dist/licenses/github-copilot-sdk-LICENSE.txt +21 -0
  54. package/dist/licenses/memory-dependency-notices.txt +3319 -0
  55. package/dist/licenses/openarchflow-LICENSE.txt +21 -0
  56. package/dist/licenses/python-dependency-notices.txt +11951 -0
  57. package/docs/upstream-lock.json +26 -0
  58. package/knowledge/engineering-practices.json +536 -0
  59. package/package.json +30 -4
  60. package/packaging/uv-release-lock.json +54 -0
  61. package/public/licenses/aws-architect-LICENSE.txt +17 -0
  62. package/public/licenses/aws-mcp-LICENSE.txt +175 -0
  63. package/public/licenses/aws-mcp-NOTICE.txt +1 -0
  64. package/public/licenses/cloud-emulation-notices.txt +36619 -0
  65. package/public/licenses/dependency-notices.txt +6379 -0
  66. package/public/licenses/emulation-notices.txt +717 -0
  67. package/public/licenses/github-copilot-sdk-LICENSE.txt +21 -0
  68. package/public/licenses/memory-dependency-notices.txt +3319 -0
  69. package/public/licenses/openarchflow-LICENSE.txt +21 -0
  70. package/public/licenses/python-dependency-notices.txt +11951 -0
  71. package/scripts/terraform-render.mjs +8 -0
  72. package/server/__init__.py +0 -0
  73. package/server/abstraction.py +28 -0
  74. package/server/agent_runtime.py +153 -0
  75. package/server/app.py +257 -0
  76. package/server/architect.py +112 -0
  77. package/server/architecture_activity.py +67 -0
  78. package/server/attachments.py +101 -0
  79. package/server/cloud-emulation-requirements.txt +29 -0
  80. package/server/codex_app_server.py +219 -0
  81. package/server/codex_engineering_backend.py +266 -0
  82. package/server/codex_worker_policy.py +170 -0
  83. package/server/contracts.py +315 -0
  84. package/server/copilot_worker.py +16 -0
  85. package/server/dependency_mirror.py +54 -0
  86. package/server/design_patch.py +43 -0
  87. package/server/emulation-requirements.txt +8 -0
  88. package/server/emulation_adapters.py +20 -0
  89. package/server/emulation_routes.py +98 -0
  90. package/server/emulation_worker.py +351 -0
  91. package/server/engineering_artifacts.py +215 -0
  92. package/server/engineering_assets/application-runtime.json +4372 -0
  93. package/server/engineering_assets/architecture_work.schema.json +79 -0
  94. package/server/engineering_assets/materialize_runtime.py +62 -0
  95. package/server/engineering_assets/prepare_tools.py +96 -0
  96. package/server/engineering_assets/sql_validation.py +59 -0
  97. package/server/engineering_contexts.py +120 -0
  98. package/server/engineering_delivery.py +210 -0
  99. package/server/engineering_finalization.py +210 -0
  100. package/server/engineering_handoff.py +163 -0
  101. package/server/engineering_jobs.py +206 -0
  102. package/server/engineering_knowledge.py +75 -0
  103. package/server/engineering_reconciliation.py +159 -0
  104. package/server/engineering_routes.py +469 -0
  105. package/server/engineering_sessions.py +273 -0
  106. package/server/engineering_tools.py +166 -0
  107. package/server/generation_lint.py +18 -0
  108. package/server/local_providers.py +181 -0
  109. package/server/local_validation.py +236 -0
  110. package/server/memory-requirements.lock +181 -0
  111. package/server/memory-requirements.txt +6 -0
  112. package/server/memory_routes.py +82 -0
  113. package/server/memory_service.py +273 -0
  114. package/server/memory_worker.py +66 -0
  115. package/server/openai_voice.py +80 -0
  116. package/server/packaged_app.py +9 -0
  117. package/server/pricing.py +84 -0
  118. package/server/process_control_observation.py +31 -0
  119. package/server/prompts.py +123 -0
  120. package/server/public_faq_emulation_worker.py +44 -0
  121. package/server/requirements.lock +1618 -0
  122. package/server/requirements.txt +68 -0
  123. package/server/runtime_dependency_locks.py +27 -0
  124. package/server/runtime_evidence.py +93 -0
  125. package/server/settings.py +14 -0
  126. package/server/skills.py +103 -0
  127. package/server/storage_emulation_worker.py +160 -0
  128. package/server/structured_emulation_worker.py +48 -0
  129. package/server/terraform_routes.py +118 -0
  130. package/server/upstream/__init__.py +0 -0
  131. package/server/upstream/agent/__init__.py +1 -0
  132. package/server/upstream/agent/aws_architect.py +600 -0
  133. package/server/upstream/agent/config/__init__.py +1 -0
  134. package/server/upstream/agent/config/agent_config.py +82 -0
  135. package/server/upstream/agent/config/prompts.py +138 -0
  136. package/server/upstream/agent/rate_limiter.py +62 -0
  137. package/server/upstream/utils/__init__.py +1 -0
  138. package/server/upstream/utils/file_writer.py +43 -0
  139. package/server/validation_applicability.py +85 -0
  140. package/server/validation_jobs.py +252 -0
  141. package/server/validation_workers.py +48 -0
  142. package/server/voice_routes.py +91 -0
  143. package/server/voice_worker.py +26 -0
  144. package/specs/028-convergence-evaluation/evidence/20261110-ibm-invoice-native/registry-structured/qualification.json +72 -0
  145. package/specs/028-convergence-evaluation/evidence/20261110-invoice-runtime/durable-current/receipt.json +61 -0
  146. package/specs/029-general-purpose-engine/evidence/20261111-runtime-dependencies/sdk/receipt.json +22 -0
  147. package/src/ArchitectureActivity.jsx +54 -0
  148. package/src/ArchitectureWorkPanel.jsx +46 -0
  149. package/src/ArtifactChecks.jsx +49 -0
  150. package/src/BlockRequirements.jsx +13 -0
  151. package/src/BrainActivity.jsx +11 -0
  152. package/src/ChatMessage.jsx +19 -0
  153. package/src/ChatResizeHandle.jsx +6 -0
  154. package/src/CodePreview.jsx +8 -0
  155. package/src/ComponentReview.jsx +31 -0
  156. package/src/DeliveryViews.jsx +59 -0
  157. package/src/EmulationPanel.jsx +44 -0
  158. package/src/EngagementViews.jsx +385 -0
  159. package/src/EngineeringPanel.jsx +151 -0
  160. package/src/ImplementationDelivery.jsx +55 -0
  161. package/src/JourneyViews.jsx +400 -0
  162. package/src/MemoryPanel.jsx +46 -0
  163. package/src/OpenAIVoicePanel.jsx +65 -0
  164. package/src/OutputsView.jsx +65 -0
  165. package/src/TerraformView.jsx +57 -0
  166. package/src/WorkbenchDialogs.jsx +532 -0
  167. package/src/activity-presentation.mjs +28 -0
  168. package/src/ai-qualification-scenarios.mjs +31 -0
  169. package/src/approval-application-files.mjs +32 -0
  170. package/src/approval-applications.mjs +82 -0
  171. package/src/approval-spec-kit.mjs +30 -0
  172. package/src/architecture-activity.css +28 -0
  173. package/src/architecture-activity.mjs +63 -0
  174. package/src/architecture-work.mjs +176 -0
  175. package/src/artifact-work.mjs +103 -0
  176. package/src/async-documents.mjs +191 -0
  177. package/src/atflow.css +1140 -0
  178. package/src/atforma.css +748 -0
  179. package/src/atmem-tokens.css +79 -0
  180. package/src/aws-preflight.mjs +60 -0
  181. package/src/aws-public-faq.mjs +102 -0
  182. package/src/aws-validation-scenarios.mjs +10 -0
  183. package/src/aws-validation.mjs +48 -0
  184. package/src/azure-plan-mocks.mjs +25 -0
  185. package/src/azure-structured.mjs +133 -0
  186. package/src/bedrock-summary.mjs +152 -0
  187. package/src/bounded-rag.mjs +60 -0
  188. package/src/brand.css +9 -0
  189. package/src/canvas-view.mjs +28 -0
  190. package/src/capability-composition.mjs +44 -0
  191. package/src/chat-attachments.mjs +13 -0
  192. package/src/cloud-provider-locks.mjs +9 -0
  193. package/src/cloud-storage-scenarios.mjs +2 -0
  194. package/src/component-review.mjs +55 -0
  195. package/src/composition-spec-kit.mjs +30 -0
  196. package/src/consultation-context.mjs +15 -0
  197. package/src/consultation.mjs +52 -0
  198. package/src/container-contracts.mjs +5 -0
  199. package/src/container-inspection.mjs +75 -0
  200. package/src/container-runtime.mjs +30 -0
  201. package/src/container-security-inspection.mjs +49 -0
  202. package/src/container-terraform.mjs +109 -0
  203. package/src/conversation.mjs +17 -0
  204. package/src/core.mjs +863 -0
  205. package/src/cross-cloud-storage.mjs +100 -0
  206. package/src/delivery-capabilities.mjs +25 -0
  207. package/src/delivery.mjs +58 -0
  208. package/src/deployment-ownership.mjs +10 -0
  209. package/src/deployment-region.mjs +11 -0
  210. package/src/derive.mjs +31 -0
  211. package/src/design-build-flow.mjs +10 -0
  212. package/src/diagram-attention.mjs +24 -0
  213. package/src/discovery.mjs +359 -0
  214. package/src/document.mjs +170 -0
  215. package/src/emulation-feedback.mjs +61 -0
  216. package/src/emulation-guidance.mjs +37 -0
  217. package/src/engagement.mjs +274 -0
  218. package/src/engineering-client.mjs +73 -0
  219. package/src/engineering-defaults.mjs +17 -0
  220. package/src/engineering.css +31 -0
  221. package/src/enterprise-application.mjs +76 -0
  222. package/src/enterprise-aws-host-infrastructure.mjs +62 -0
  223. package/src/enterprise-aws-host-tests.mjs +15 -0
  224. package/src/enterprise-aws-infrastructure-tests.mjs +38 -0
  225. package/src/enterprise-aws-infrastructure.mjs +138 -0
  226. package/src/enterprise-google-infrastructure.mjs +84 -0
  227. package/src/enterprise-google-tests.mjs +25 -0
  228. package/src/estimate.mjs +188 -0
  229. package/src/existing-references.mjs +18 -0
  230. package/src/external-identities.mjs +17 -0
  231. package/src/faq-lambda-build.mjs +28 -0
  232. package/src/gcp-structured.mjs +104 -0
  233. package/src/generation-provider.mjs +7 -0
  234. package/src/generation-quality.mjs +69 -0
  235. package/src/handoff.mjs +141 -0
  236. package/src/ibm-registry.mjs +12 -0
  237. package/src/ibm-structured.mjs +103 -0
  238. package/src/identifiers.mjs +15 -0
  239. package/src/implementation-map.mjs +14 -0
  240. package/src/implementation-outcome.mjs +8 -0
  241. package/src/incomplete-terraform.mjs +9 -0
  242. package/src/integrations.ts +137 -0
  243. package/src/interface-contracts.mjs +30 -0
  244. package/src/invoice-application.mjs +66 -0
  245. package/src/invoice-aws-operations.mjs +136 -0
  246. package/src/invoice-aws.mjs +143 -0
  247. package/src/invoice-azure-operations.mjs +147 -0
  248. package/src/invoice-azure.mjs +134 -0
  249. package/src/invoice-builder.mjs +35 -0
  250. package/src/invoice-dependencies.mjs +43 -0
  251. package/src/invoice-gcp-operations.mjs +178 -0
  252. package/src/invoice-gcp.mjs +104 -0
  253. package/src/invoice-ibm-operations.mjs +278 -0
  254. package/src/invoice-ibm.mjs +142 -0
  255. package/src/invoice-operations.mjs +143 -0
  256. package/src/invoice-plan.mjs +45 -0
  257. package/src/invoice-region.mjs +6 -0
  258. package/src/invoice-spec-kit.mjs +61 -0
  259. package/src/invoice-state.mjs +7 -0
  260. package/src/invoice-terraform.mjs +29 -0
  261. package/src/invoice-tests.mjs +122 -0
  262. package/src/journey-workspace.css +72 -0
  263. package/src/journey.mjs +87 -0
  264. package/src/levels.mjs +145 -0
  265. package/src/local-agent.mjs +184 -0
  266. package/src/main.jsx +2458 -0
  267. package/src/model-policy-preflight.mjs +34 -0
  268. package/src/openai-voice.mjs +102 -0
  269. package/src/output-bundle.mjs +11 -0
  270. package/src/ownership-inspection.mjs +28 -0
  271. package/src/pack.mjs +201 -0
  272. package/src/pricing.mjs +31 -0
  273. package/src/production-state.mjs +8 -0
  274. package/src/project-copy.mjs +10 -0
  275. package/src/project-file.mjs +160 -0
  276. package/src/project-links.mjs +3 -0
  277. package/src/protected-state.mjs +43 -0
  278. package/src/public-faq-builder.mjs +19 -0
  279. package/src/public-faq-clouds.mjs +251 -0
  280. package/src/public-faq.mjs +122 -0
  281. package/src/pulumi.mjs +123 -0
  282. package/src/python-container.mjs +25 -0
  283. package/src/python-runtime.mjs +50 -0
  284. package/src/rag-handler.mjs +43 -0
  285. package/src/rag-web-assets.mjs +52 -0
  286. package/src/rag-web.mjs +68 -0
  287. package/src/records.mjs +177 -0
  288. package/src/resources.mjs +163 -0
  289. package/src/review.mjs +252 -0
  290. package/src/runtime/EnterpriseDocument.java +89 -0
  291. package/src/runtime/approved_http_destination.py +72 -0
  292. package/src/runtime/aws-lambda-qualification-lock.json +7 -0
  293. package/src/runtime/aws-python-lock.json +82 -0
  294. package/src/runtime/aws-web-python-lock.json +887 -0
  295. package/src/runtime/aws_json_model.py +42 -0
  296. package/src/runtime/azure-python-lock.json +863 -0
  297. package/src/runtime/azure-sources.json +8 -0
  298. package/src/runtime/azure-test-lock.json +23 -0
  299. package/src/runtime/azure_acceptance.py +192 -0
  300. package/src/runtime/azure_structured.py +153 -0
  301. package/src/runtime/bounded_rag.py +126 -0
  302. package/src/runtime/catalog_admin.py +70 -0
  303. package/src/runtime/cloud-sql-proxy-lock.json +8 -0
  304. package/src/runtime/cloud-sql-proxy-security-review.json +30 -0
  305. package/src/runtime/connector_cli.py +50 -0
  306. package/src/runtime/connector_sync.py +70 -0
  307. package/src/runtime/durable-python-lock.json +247 -0
  308. package/src/runtime/durable_workflow.py +325 -0
  309. package/src/runtime/enterprise-application-manifest.json +110 -0
  310. package/src/runtime/enterprise-application-sources.json +266 -0
  311. package/src/runtime/enterprise-auth-python-lock.json +592 -0
  312. package/src/runtime/enterprise-aws-host-bootstrap-source.json +1 -0
  313. package/src/runtime/enterprise-aws-host-probe-source.json +1 -0
  314. package/src/runtime/enterprise-aws-task-template.json +235 -0
  315. package/src/runtime/enterprise-document-lock.json +18 -0
  316. package/src/runtime/enterprise-document.Dockerfile +15 -0
  317. package/src/runtime/enterprise-runtime-aws-python-lock.json +1115 -0
  318. package/src/runtime/enterprise-runtime-azure-python-lock.json +1106 -0
  319. package/src/runtime/enterprise-runtime-gcp-python-lock.json +1060 -0
  320. package/src/runtime/enterprise-runtime-ibm-python-lock.json +1096 -0
  321. package/src/runtime/enterprise-runtime-python-lock.json +1058 -0
  322. package/src/runtime/enterprise-runtime.Dockerfile +15 -0
  323. package/src/runtime/enterprise-web-app.js +1 -0
  324. package/src/runtime/enterprise-web-entry.js +105 -0
  325. package/src/runtime/enterprise-web-lock.json +29 -0
  326. package/src/runtime/enterprise-web-notices.txt +229 -0
  327. package/src/runtime/enterprise-web.css +4 -0
  328. package/src/runtime/enterprise-web.html +8 -0
  329. package/src/runtime/enterprise_audit.py +91 -0
  330. package/src/runtime/enterprise_audit_schema.sql +25 -0
  331. package/src/runtime/enterprise_auth_schema.sql +67 -0
  332. package/src/runtime/enterprise_auth_store.py +241 -0
  333. package/src/runtime/enterprise_aws_host_bootstrap.py +120 -0
  334. package/src/runtime/enterprise_aws_host_probe.py +105 -0
  335. package/src/runtime/enterprise_aws_hosts.py +136 -0
  336. package/src/runtime/enterprise_aws_jobs.py +300 -0
  337. package/src/runtime/enterprise_aws_objects.py +93 -0
  338. package/src/runtime/enterprise_aws_transfer.py +83 -0
  339. package/src/runtime/enterprise_azure_batch_api.py +128 -0
  340. package/src/runtime/enterprise_azure_host.py +599 -0
  341. package/src/runtime/enterprise_azure_jobs.py +294 -0
  342. package/src/runtime/enterprise_azure_objects.py +234 -0
  343. package/src/runtime/enterprise_azure_pool.py +161 -0
  344. package/src/runtime/enterprise_azure_transfer.py +122 -0
  345. package/src/runtime/enterprise_configuration.py +136 -0
  346. package/src/runtime/enterprise_document.py +116 -0
  347. package/src/runtime/enterprise_document_cli.py +32 -0
  348. package/src/runtime/enterprise_document_contract.py +54 -0
  349. package/src/runtime/enterprise_document_job.py +109 -0
  350. package/src/runtime/enterprise_document_jobs.py +122 -0
  351. package/src/runtime/enterprise_document_jobs_schema.sql +23 -0
  352. package/src/runtime/enterprise_extraction_cache.py +186 -0
  353. package/src/runtime/enterprise_extraction_schema.sql +17 -0
  354. package/src/runtime/enterprise_google_jobs.py +275 -0
  355. package/src/runtime/enterprise_google_transfer.py +85 -0
  356. package/src/runtime/enterprise_http.py +212 -0
  357. package/src/runtime/enterprise_identity.py +52 -0
  358. package/src/runtime/enterprise_knowledge.py +152 -0
  359. package/src/runtime/enterprise_models.py +94 -0
  360. package/src/runtime/enterprise_native.py +181 -0
  361. package/src/runtime/enterprise_oauth.py +132 -0
  362. package/src/runtime/enterprise_operator.py +160 -0
  363. package/src/runtime/enterprise_parser_service.py +136 -0
  364. package/src/runtime/enterprise_parser_transport.py +68 -0
  365. package/src/runtime/enterprise_queries.py +255 -0
  366. package/src/runtime/enterprise_queries_schema.sql +27 -0
  367. package/src/runtime/enterprise_query_service.py +111 -0
  368. package/src/runtime/enterprise_secrets.py +110 -0
  369. package/src/runtime/enterprise_sessions.py +95 -0
  370. package/src/runtime/enterprise_sources.py +260 -0
  371. package/src/runtime/enterprise_web.py +39 -0
  372. package/src/runtime/enterprise_worker.py +68 -0
  373. package/src/runtime/export_contract_acceptance.py +18 -0
  374. package/src/runtime/faq-output-contract.json +40 -0
  375. package/src/runtime/faq-web-app.js +41 -0
  376. package/src/runtime/faq-web.css +1 -0
  377. package/src/runtime/faq-web.html +6 -0
  378. package/src/runtime/gcp-sources.json +9 -0
  379. package/src/runtime/gcp_acceptance.py +110 -0
  380. package/src/runtime/gcp_structured.py +150 -0
  381. package/src/runtime/http_acceptance.py +39 -0
  382. package/src/runtime/iap-web-app.js +36 -0
  383. package/src/runtime/iap-web-source.json +1 -0
  384. package/src/runtime/ibm-python-lock.json +856 -0
  385. package/src/runtime/ibm-sources.json +9 -0
  386. package/src/runtime/ibm_acceptance.py +133 -0
  387. package/src/runtime/ibm_structured.py +113 -0
  388. package/src/runtime/invoice-azapi-provider-lock.json +7 -0
  389. package/src/runtime/invoice-ibm-provider-lock.json +7 -0
  390. package/src/runtime/invoice-parser-lock.json +1199 -0
  391. package/src/runtime/invoice-parser-python-lock.json +56 -0
  392. package/src/runtime/invoice-parser.Dockerfile +190 -0
  393. package/src/runtime/invoice-sources.json +58 -0
  394. package/src/runtime/invoice-test-sources.json +24 -0
  395. package/src/runtime/invoice-web.css +2 -0
  396. package/src/runtime/invoice-web.html +12 -0
  397. package/src/runtime/invoice-web.js +112 -0
  398. package/src/runtime/invoice_configuration.py +17 -0
  399. package/src/runtime/invoice_document.py +95 -0
  400. package/src/runtime/invoice_extraction.py +96 -0
  401. package/src/runtime/invoice_http.py +129 -0
  402. package/src/runtime/invoice_identity.py +5 -0
  403. package/src/runtime/invoice_maintenance.py +40 -0
  404. package/src/runtime/invoice_native.py +77 -0
  405. package/src/runtime/invoice_object_store.py +153 -0
  406. package/src/runtime/invoice_operations.py +108 -0
  407. package/src/runtime/invoice_operator.py +79 -0
  408. package/src/runtime/invoice_operator_core.py +39 -0
  409. package/src/runtime/invoice_operator_job.py +147 -0
  410. package/src/runtime/invoice_parser_cli.py +17 -0
  411. package/src/runtime/invoice_parser_identity.py +39 -0
  412. package/src/runtime/invoice_parser_service.py +89 -0
  413. package/src/runtime/invoice_parser_transport.py +89 -0
  414. package/src/runtime/invoice_processing.py +24 -0
  415. package/src/runtime/invoice_retention.py +16 -0
  416. package/src/runtime/invoice_runtime_secrets.py +43 -0
  417. package/src/runtime/invoice_stage.py +80 -0
  418. package/src/runtime/invoice_web.py +39 -0
  419. package/src/runtime/invoice_worker.py +50 -0
  420. package/src/runtime/lambda_faq.py +5 -0
  421. package/src/runtime/parser-requirements.lock +4 -0
  422. package/src/runtime/policy_review.py +18 -0
  423. package/src/runtime/postgres-qualification-lock.json +21 -0
  424. package/src/runtime/public-faq-sources.json +22 -0
  425. package/src/runtime/public_catalog_admin.py +122 -0
  426. package/src/runtime/public_catalog_store.py +125 -0
  427. package/src/runtime/public_faq.py +144 -0
  428. package/src/runtime/public_faq_app.py +49 -0
  429. package/src/runtime/python-container-lock.json +18 -0
  430. package/src/runtime/rag-sources.json +10 -0
  431. package/src/runtime/rag_acceptance.py +60 -0
  432. package/src/runtime/rag_aws_adapter.py +95 -0
  433. package/src/runtime/rds-ca-source.json +9 -0
  434. package/src/runtime/rds-global-ca.pem +2888 -0
  435. package/src/runtime/state-contract-check-source.json +4 -0
  436. package/src/runtime/state_contract_check.py +338 -0
  437. package/src/runtime/structured-source.json +1 -0
  438. package/src/runtime/structured-web-app.js +71 -0
  439. package/src/runtime/structured-web-source.json +1 -0
  440. package/src/runtime/structured_http.py +105 -0
  441. package/src/runtime/structured_output.py +48 -0
  442. package/src/runtime/web-python-lock.json +802 -0
  443. package/src/runtime/web_user_admin.py +44 -0
  444. package/src/runtime/workflow_application.py +62 -0
  445. package/src/runtime/workflow_bindings.py +128 -0
  446. package/src/runtime/workflow_configuration.py +40 -0
  447. package/src/runtime/workflow_connection.py +105 -0
  448. package/src/runtime/workflow_contract.py +54 -0
  449. package/src/runtime/workflow_database.py +94 -0
  450. package/src/runtime/workflow_errors.py +6 -0
  451. package/src/runtime/workflow_http.py +178 -0
  452. package/src/runtime/workflow_identity.py +69 -0
  453. package/src/runtime/workflow_payload.py +118 -0
  454. package/src/runtime/workflow_process_stage.py +88 -0
  455. package/src/runtime/workflow_profile.py +91 -0
  456. package/src/runtime/workflow_review.py +106 -0
  457. package/src/runtime/workflow_role_bootstrap.py +104 -0
  458. package/src/runtime/workflow_schema.sql +72 -0
  459. package/src/runtime/workflow_worker.py +142 -0
  460. package/src/runtime-settings.mjs +15 -0
  461. package/src/s3-access.mjs +14 -0
  462. package/src/source-contracts.mjs +17 -0
  463. package/src/spec-kit.mjs +186 -0
  464. package/src/state-custody.mjs +32 -0
  465. package/src/state-inspection.mjs +45 -0
  466. package/src/state-spec-kit.mjs +13 -0
  467. package/src/storage-tests.mjs +25 -0
  468. package/src/structured-api.mjs +133 -0
  469. package/src/structured-contract.mjs +19 -0
  470. package/src/structured-operation-policy.mjs +2 -0
  471. package/src/structured-web.mjs +17 -0
  472. package/src/style.css +1 -0
  473. package/src/system-description.mjs +26 -0
  474. package/src/terraform-admission.mjs +66 -0
  475. package/src/terraform-composition.mjs +83 -0
  476. package/src/terraform-expressions.mjs +46 -0
  477. package/src/terraform-validation-coverage.mjs +11 -0
  478. package/src/terraform.mjs +128 -0
  479. package/src/text-statistics.mjs +51 -0
  480. package/src/upstream/openarchflow/format-payload.ts +26 -0
  481. package/src/upstream/openarchflow/import/mermaid.ts +205 -0
  482. package/src/upstream/openarchflow/import/sql-ddl.ts +109 -0
  483. package/src/upstream/openarchflow/layout.ts +54 -0
  484. package/src/upstream/openarchflow/providers/aws.ts +196 -0
  485. package/src/upstream/openarchflow/providers/azure.ts +126 -0
  486. package/src/upstream/openarchflow/providers/cloudnative.ts +71 -0
  487. package/src/upstream/openarchflow/providers/generic.ts +227 -0
  488. package/src/upstream/openarchflow/providers/integration.ts +22 -0
  489. package/src/upstream/openarchflow/providers/types.ts +2 -0
  490. package/src/upstream/openarchflow/templates.ts +937 -0
  491. package/src/upstream-catalog.mjs +10 -0
  492. package/src/useChatScroll.jsx +36 -0
  493. package/src/useEmulation.jsx +36 -0
  494. package/src/validation-receipt.mjs +10 -0
  495. package/src/visual-export.mjs +92 -0
  496. package/src/voice-conversation.mjs +117 -0
  497. package/src/work-intake.mjs +24 -0
  498. package/src/workflow-runtime-inventory.mjs +3 -0
@@ -0,0 +1,325 @@
1
+ """Transactional state and approval fences for owned application workflows.
2
+
3
+ The HTTP/identity adapter must construct Principal only after native verification.
4
+ Live application membership is checked here; this is not an OIDC implementation.
5
+ Workers have a separate internal API. No model text chooses a task, role or state.
6
+ No queue lock alone establishes exactly-once external side effects: dispatch must
7
+ use a verified upstream idempotency contract and preserve the operation identity.
8
+ """
9
+ from dataclasses import dataclass
10
+ import hashlib
11
+ import json
12
+ import uuid
13
+ import psycopg
14
+ from psycopg.rows import dict_row
15
+ from psycopg.types.json import Json,Jsonb
16
+ from workflow_contract import bind_review_policy
17
+ from workflow_database import require_current_schema
18
+
19
+ class Denied(PermissionError):pass
20
+ class Missing(LookupError):pass
21
+ class Conflict(ValueError):pass
22
+ class LostLease(Conflict):pass
23
+
24
+ def identifier(value):
25
+ if not isinstance(value,str):raise ValueError('An exact UUID is required')
26
+ parsed=uuid.UUID(value)
27
+ if str(parsed)!=value:raise ValueError('Use a canonical UUID')
28
+ return value
29
+
30
+ def canonical(value,limit=64000):
31
+ if not isinstance(value,dict) or any(not isinstance(k,str) for k in value):raise ValueError('A JSON object is required')
32
+ try:raw=json.dumps(value,sort_keys=True,separators=(',',':'),ensure_ascii=False,allow_nan=False).encode('utf-8')
33
+ except (ValueError,TypeError,UnicodeError,RecursionError):raise ValueError('Invalid bounded JSON') from None
34
+ if len(raw)>limit:raise ValueError('JSON exceeds its boundary')
35
+ return raw
36
+
37
+ def stored_json(value):
38
+ # Canonical UTF8 preserves the validated size. Default ASCII escaping can
39
+ # expand a valid non-BMP payload beyond its SQL history bound.
40
+ return Json(value,dumps=lambda item:canonical(item).decode('utf-8'))
41
+
42
+ @dataclass(frozen=True)
43
+ class Principal:
44
+ account_id:str
45
+ subject:str
46
+ def __post_init__(self):
47
+ identifier(self.account_id)
48
+ if not isinstance(self.subject,str) or not 1<=len(self.subject.encode('utf-8'))<=500 or any(ord(c)<32 for c in self.subject):raise ValueError('Invalid verified subject')
49
+
50
+ class WorkflowStore:
51
+ def __init__(self,dsn,extract_task,dispatch_task,*,destination_contract,max_attempts=5,lease_seconds=600,payload_contract=None,operation_kind=None,review_policy=None):
52
+ self.destination_contract=bind_review_policy(destination_contract,payload_contract,review_policy)
53
+ self.payload_contract=payload_contract
54
+ self.review_policy=review_policy
55
+ if operation_kind is not None and(type(operation_kind)is not str or operation_kind not in {'document','draft','account_change'}):raise ValueError('Use an owned operation policy')
56
+ self.operation_kind=operation_kind
57
+ if not callable(dsn)and(not isinstance(dsn,str) or not dsn):raise ValueError('Supply an operator-managed PostgreSQL connection or trusted credential factory')
58
+ if type(max_attempts)is not int or not 1<=max_attempts<=10 or type(lease_seconds)is not int or not 10<=lease_seconds<=1800:raise ValueError('Invalid owned workflow limits')
59
+ for task in [extract_task,dispatch_task]:
60
+ queue=getattr(task,'queue',None)
61
+ if not isinstance(queue,str) or not 1<=len(queue.encode('utf-8'))<=40:raise ValueError('Owned queue names must fit PostgreSQL notification channels')
62
+ if getattr(task,'queueing_lock',None)is not None:raise ValueError('Domain-fenced workflow tasks must not inherit a queueing lock')
63
+ self.workflow_key=extract_task.name
64
+ if not isinstance(self.workflow_key,str) or not 1<=len(self.workflow_key.encode())<=128:raise ValueError('Invalid owned workflow identity')
65
+ self.dsn=dsn;self.tasks={'extract':extract_task,'dispatch':dispatch_task};self.max_attempts=max_attempts;self.lease_seconds=lease_seconds
66
+ def connect(self):
67
+ value=self.dsn()if callable(self.dsn)else self.dsn
68
+ if not isinstance(value,str)or not value:raise ValueError('Database credential factory did not return an owned connection')
69
+ conn=psycopg.connect(value,connect_timeout=5,row_factory=dict_row,options='-c search_path=pg_catalog,workflow,pg_temp -c statement_timeout=10000 -c lock_timeout=3000')
70
+ try:require_current_schema(conn)
71
+ except Exception:
72
+ conn.close();raise
73
+ return conn
74
+ def _actor(self,conn,actor,roles):
75
+ if not isinstance(actor,Principal):raise Denied('Verified application identity required')
76
+ row=conn.execute('SELECT active,roles FROM workflow.memberships WHERE account_id=%s AND subject=%s FOR SHARE',(actor.account_id,actor.subject)).fetchone()
77
+ if not row or not row['active'] or not set(row['roles']).intersection(roles):raise Denied('Current application membership does not authorize this operation')
78
+ return set(row['roles'])
79
+ def _row(self,conn,operation_id,account_id=None,*,lock=True):
80
+ identifier(operation_id)
81
+ query='SELECT * FROM workflow.operations WHERE id=%s AND workflow_key=%s';params=[operation_id,self.workflow_key]
82
+ if account_id is not None:query+=' AND account_id=%s';params.append(account_id)
83
+ if lock:query+=' FOR UPDATE'
84
+ row=conn.execute(query,params).fetchone()
85
+ if not row:raise Missing('Operation unavailable')
86
+ return row
87
+ def _payload(self,side,value):
88
+ expected=self.review_policy.sha256 if self.review_policy else None
89
+ if self.destination_contract.get('reviewPolicySha256')!=expected:raise Conflict('Review policy binding changed')
90
+ if self.review_policy:self.review_policy.ensure_current()
91
+ bound=self.destination_contract.get('payloadContractSha256')
92
+ if bound!=(self.payload_contract.sha256 if self.payload_contract else None):raise Conflict('Application contract binding changed')
93
+ canonical(value)
94
+ return self.payload_contract.validate(side,value)if self.payload_contract else json.loads(canonical(value))
95
+ def _contract(self,row,*,result=False):
96
+ if row['destination_contract']!=self.destination_contract:raise Conflict('Application/destination contract changed; explicit reconciliation is required')
97
+ if self.operation_kind is not None and row['kind']!=self.operation_kind:raise Conflict('Operation policy differs from this application')
98
+ self._payload('source',row['source_ref'])
99
+ if result:
100
+ self._payload('result',row['result'])
101
+ if self.review_policy:self.review_policy.validate_result(row['source_ref'],row['result'])
102
+ def _event(self,conn,row,event,actor,detail=None):
103
+ if event not in {'submitted','claimed','result_ready','edited','approved','dispatch_claimed','sent','retry_pending','outcome_unknown','dead','recovered','approval_revoked','review_inspected'}:raise ValueError('Unknown owned audit event')
104
+ detail=detail or {};canonical(detail,1500)
105
+ conn.execute('INSERT INTO workflow.events(operation_id,account_id,event,actor,detail) VALUES(%s,%s,%s,%s,%s)',(row['id'],row['account_id'],event,actor,Jsonb(detail)))
106
+ def _enqueue(self,conn,kind,operation_id):
107
+ # Library API executes the queue INSERT on this exact transaction/connection.
108
+ # Args contain identity only, never raw documents, prompts or credentials.
109
+ # Domain row locks/unique identities already deduplicate submissions and
110
+ # approvals. A queueing_lock could prevent retrying a stalled doing job
111
+ # when a recovery notification is already todo, trapping both behind its
112
+ # execution lock. Duplicate notifications are harmless; domain leases and
113
+ # immutable approvals fence them independently of the queue's job status.
114
+ return self.tasks[kind].configure(connection=conn,lock=str(operation_id)).defer(operation_id=str(operation_id))
115
+ def submit(self,actor,kind,dedup_key,source_ref):
116
+ if kind not in {'document','draft','account_change'}:raise ValueError('Unsupported owned operation kind')
117
+ if self.operation_kind is not None and kind!=self.operation_kind:raise ValueError('Operation policy differs from this application')
118
+ if not isinstance(dedup_key,str) or not 1<=len(dedup_key.encode())<=200:raise ValueError('Invalid stable operation identity')
119
+ source_ref=self._payload('source',source_ref)
120
+ with self.connect()as conn:
121
+ self._actor(conn,actor,{'user','reviewer','supervisor','owner'})
122
+ new=str(uuid.uuid4())
123
+ row=conn.execute("INSERT INTO workflow.operations(id,account_id,workflow_key,kind,dedup_key,created_by,source_ref,destination_contract,state) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,'pending') ON CONFLICT(account_id,workflow_key,kind,dedup_key) DO NOTHING RETURNING *",(new,actor.account_id,self.workflow_key,kind,dedup_key,actor.subject,stored_json(source_ref),Jsonb(self.destination_contract))).fetchone()
124
+ if not row:
125
+ row=conn.execute('SELECT * FROM workflow.operations WHERE account_id=%s AND workflow_key=%s AND kind=%s AND dedup_key=%s',(actor.account_id,self.workflow_key,kind,dedup_key)).fetchone()
126
+ if self.review_policy and row['created_by']!=actor.subject:raise Conflict('Stable operation identity belongs to another submitter')
127
+ if canonical(row['source_ref'])!=canonical(source_ref):raise Conflict('Stable identity cannot refer to a changed source')
128
+ if row['destination_contract']!=self.destination_contract:raise Conflict('Stable identity cannot silently move to another destination contract')
129
+ return str(row['id'])
130
+ job=self._enqueue(conn,'extract',row['id']);conn.execute('UPDATE workflow.operations SET queue_job_id=%s WHERE id=%s',(job,row['id']));self._event(conn,row,'submitted',actor.subject)
131
+ return str(row['id'])
132
+ def get(self,actor,operation_id):
133
+ with self.connect()as conn:
134
+ roles=self._actor(conn,actor,{'user','reviewer','supervisor','owner'});row=self._row(conn,operation_id,actor.account_id,lock=False)
135
+ self._readable(actor,roles,row);return row
136
+ def _owner_reads(self,roles):
137
+ return bool(self.review_policy and self.review_policy.data['readScope']=='owner'and not roles.intersection({'reviewer','supervisor','owner'}))
138
+ def _readable(self,actor,roles,row):
139
+ if self._owner_reads(roles)and row['created_by']!=actor.subject:raise Missing('Operation unavailable')
140
+ def authorize(self,actor):
141
+ with self.connect()as conn:
142
+ self._actor(conn,actor,{'user','reviewer','supervisor','owner'})
143
+ return conn.execute('SELECT roles FROM workflow.memberships WHERE account_id=%s AND subject=%s',(actor.account_id,actor.subject)).fetchone()['roles']
144
+ def list(self,actor,*,before=None,limit=25):
145
+ if type(limit)is not int or not 1<=limit<=50:raise ValueError('Invalid bounded review page')
146
+ with self.connect()as conn:
147
+ roles=self._actor(conn,actor,{'user','reviewer','supervisor','owner'})
148
+ query='SELECT * FROM workflow.operations WHERE account_id=%s AND workflow_key=%s';params=[actor.account_id,self.workflow_key]
149
+ if self._owner_reads(roles):query+=' AND created_by=%s';params.append(actor.subject)
150
+ if before is not None:
151
+ anchor=self._row(conn,before,actor.account_id,lock=False)
152
+ self._readable(actor,roles,anchor)
153
+ query+=' AND (created_at,id)<(%s,%s)';params.extend([anchor['created_at'],anchor['id']])
154
+ return conn.execute(query+' ORDER BY created_at DESC,id DESC LIMIT %s',params+[limit]).fetchall()
155
+ def events(self,actor,operation_id):
156
+ with self.connect()as conn:
157
+ roles=self._actor(conn,actor,{'user','reviewer','supervisor','owner'});row=self._row(conn,operation_id,actor.account_id,lock=False);self._readable(actor,roles,row)
158
+ return conn.execute('SELECT sequence,event,actor,detail,created_at FROM workflow.events WHERE operation_id=%s AND account_id=%s ORDER BY sequence',(operation_id,actor.account_id)).fetchall()
159
+ def result_history(self,actor,operation_id,*,after_revision=0,limit=50):
160
+ if type(after_revision)is not int or not 0<=after_revision<=2147483647 or type(limit)is not int or not 1<=limit<=50:raise ValueError('Use a bounded result history page')
161
+ with self.connect()as conn:
162
+ roles=self._actor(conn,actor,{'user','reviewer','supervisor','owner'});row=self._row(conn,operation_id,actor.account_id,lock=False);self._readable(actor,roles,row)
163
+ return conn.execute('SELECT revision,result,actor,created_at FROM workflow.results_history WHERE operation_id=%s AND account_id=%s AND revision>%s ORDER BY revision LIMIT %s',(operation_id,actor.account_id,after_revision,limit)).fetchall()
164
+ def _result_history(self,conn,row,actor):
165
+ conn.execute('INSERT INTO workflow.results_history(operation_id,account_id,revision,result,actor)VALUES(%s,%s,%s,%s,%s)',(row['id'],row['account_id'],row['result_revision'],stored_json(row['result']),actor))
166
+ def _fingerprint(self,row,result=None):
167
+ payload={'kind':row['kind'],'source':row['source_ref'],'destination':row['destination_contract'],'result':row['result']if result is None else result,'revision':row['result_revision']}
168
+ return hashlib.sha256(canonical(payload,140000)).hexdigest()
169
+ def _lease(self,conn,row,state,event):
170
+ token=str(uuid.uuid4())
171
+ updated=conn.execute('UPDATE workflow.operations SET state=%s,lease_token=%s,lease_until=clock_timestamp()+make_interval(secs=>%s),execution_epoch=execution_epoch+1,attempts=attempts+1,updated_at=clock_timestamp() WHERE id=%s RETURNING *',(state,token,self.lease_seconds,row['id'])).fetchone()
172
+ self._event(conn,updated,event,'worker',{'executionEpoch':updated['execution_epoch']});return updated
173
+ def claim_extract(self,operation_id):
174
+ with self.connect()as conn:
175
+ row=self._row(conn,operation_id)
176
+ self._contract(row)
177
+ live=conn.execute('SELECT %s::timestamptz>clock_timestamp() AS live',(row['lease_until'],)).fetchone()['live']
178
+ if row['state']not in {'pending','processing'} or (row['state']=='processing'and live):return None
179
+ if row['attempts']>=self.max_attempts:
180
+ conn.execute("UPDATE workflow.operations SET state='dead',lease_token=NULL,lease_until=NULL WHERE id=%s",(row['id'],));self._event(conn,row,'dead','worker',{'reason':'attempts_exhausted'});return None
181
+ return self._lease(conn,row,'processing','claimed')
182
+ def _check_lease(self,conn,row,token,state):
183
+ identifier(token)
184
+ live=conn.execute('SELECT %s::timestamptz>clock_timestamp() AS live',(row['lease_until'],)).fetchone()['live']
185
+ if row['state']!=state or str(row['lease_token'])!=token or not live:raise LostLease('The operation lease is no longer current')
186
+ def record_result(self,operation_id,token,result):
187
+ result=self._payload('result',result)
188
+ with self.connect()as conn:
189
+ row=self._row(conn,operation_id);self._check_lease(conn,row,token,'processing')
190
+ self._contract(row)
191
+ if self.review_policy:result=self.review_policy.validate_result(row['source_ref'],result)
192
+ updated=conn.execute("UPDATE workflow.operations SET result=%s,result_revision=result_revision+1,state='review',approved_hash=NULL,approved_by=NULL,lease_token=NULL,lease_until=NULL,attempts=0,updated_at=clock_timestamp() WHERE id=%s RETURNING *",(stored_json(result),row['id'])).fetchone();self._result_history(conn,updated,'worker');self._event(conn,updated,'result_ready','worker',{'revision':updated['result_revision']});return updated
193
+ def edit_result(self,actor,operation_id,expected_revision,result):
194
+ result=self._payload('result',result)
195
+ if type(expected_revision)is not int:raise ValueError('An exact revision is required')
196
+ with self.connect()as conn:
197
+ self._actor(conn,actor,{'reviewer','supervisor','owner'});row=self._row(conn,operation_id,actor.account_id)
198
+ self._contract(row)
199
+ if row['state']!='review' or row['result_revision']!=expected_revision:raise Conflict('Reload the current review before editing')
200
+ if self.review_policy:result=self.review_policy.validate_edit(row['source_ref'],row['result'],result)
201
+ updated=conn.execute('UPDATE workflow.operations SET result=%s,result_revision=result_revision+1,approved_hash=NULL,approved_by=NULL,updated_at=clock_timestamp() WHERE id=%s RETURNING *',(stored_json(result),row['id'])).fetchone();self._result_history(conn,updated,actor.subject);self._event(conn,updated,'edited',actor.subject,{'revision':updated['result_revision']});return updated
202
+ def inspect(self,actor,operation_id):
203
+ if not self.review_policy:raise Conflict('This application has no explicit inspection policy')
204
+ with self.connect()as conn:
205
+ initial=self._row(conn,operation_id,actor.account_id,lock=False)
206
+ roles={'supervisor','owner'}if initial['kind']=='account_change'else{'reviewer','supervisor','owner'}
207
+ self._actor(conn,actor,roles);row=self._row(conn,operation_id,actor.account_id)
208
+ self._contract(row,result=True)
209
+ if row['state']!='review':raise Conflict('The operation is not awaiting review')
210
+ self._event(conn,row,'review_inspected',actor.subject,{'revision':row['result_revision'],'payloadSha256':self._fingerprint(row)})
211
+ return row
212
+ def approve(self,actor,operation_id,expected_revision,payload_sha256=None):
213
+ if type(expected_revision)is not int:raise ValueError('An exact revision is required')
214
+ # Read ownership/kind without a row lock, then lock membership before the
215
+ # operation everywhere human authorization is involved (consistent order).
216
+ with self.connect()as conn:
217
+ initial=self._row(conn,operation_id,actor.account_id,lock=False)
218
+ if initial['destination_contract']!=self.destination_contract:raise Conflict('Destination contract changed; review its migration without replaying prior actions')
219
+ roles={'supervisor','owner'}if initial['kind']=='account_change'else{'reviewer','supervisor','owner'}
220
+ self._actor(conn,actor,roles);row=self._row(conn,operation_id,actor.account_id)
221
+ self._contract(row,result=True)
222
+ if row['result_revision']!=expected_revision or not row['result']:raise Conflict('Review the current result before approving')
223
+ if self.review_policy and payload_sha256!=self._fingerprint(row):raise Conflict('Approval must bind the inspected current payload')
224
+ if row['state']in {'approved','dispatching','unknown','sent'}:
225
+ if row['approved_hash']!=self._fingerprint(row):raise Conflict('Approved content changed')
226
+ return row
227
+ if row['state']!='review':raise Conflict('The operation is not awaiting approval')
228
+ ttl=self.review_policy.data['inspectionTtlSeconds']if self.review_policy else None
229
+ if ttl is not None:
230
+ inspection=conn.execute("SELECT 1 FROM workflow.events WHERE operation_id=%s AND account_id=%s AND actor=%s AND event='review_inspected' AND detail->>'payloadSha256'=%s AND detail->>'revision'=%s AND created_at>=clock_timestamp()-make_interval(secs=>%s) LIMIT 1",(row['id'],actor.account_id,actor.subject,payload_sha256,str(expected_revision),ttl)).fetchone()
231
+ if not inspection:raise Conflict('Inspect the exact current result before approving')
232
+ digest=self._fingerprint(row);job=self._enqueue(conn,'dispatch',row['id'])
233
+ updated=conn.execute("UPDATE workflow.operations SET state='approved',approved_hash=%s,approved_by=%s,queue_job_id=%s,attempts=0,updated_at=clock_timestamp() WHERE id=%s RETURNING *",(digest,actor.subject,job,row['id'])).fetchone();self._event(conn,updated,'approved',actor.subject,{'revision':row['result_revision'],'payloadSha256':digest});return updated
234
+ def claim_dispatch(self,operation_id,*,verified_idempotent_replay=False):
235
+ if type(verified_idempotent_replay)is not bool:raise ValueError('An explicit owned replay policy is required')
236
+ with self.connect()as conn:
237
+ initial=self._row(conn,operation_id,lock=False)
238
+ if initial['destination_contract']!=self.destination_contract:raise Conflict('Approved destination contract no longer matches this worker')
239
+ if not initial['approved_by']:return None
240
+ actor=Principal(str(initial['account_id']),initial['approved_by']);roles={'supervisor','owner'}if initial['kind']=='account_change'else{'reviewer','supervisor','owner'}
241
+ try:self._actor(conn,actor,roles)
242
+ except Denied:
243
+ row=self._row(conn,operation_id)
244
+ # Unknown means an external effect may already exist. Revocation
245
+ # cannot turn it back into a fresh review/approval/send cycle.
246
+ if row['state']=='approved':
247
+ conn.execute("UPDATE workflow.operations SET state='review',approved_by=NULL,approved_hash=NULL WHERE id=%s",(row['id'],));self._event(conn,row,'approval_revoked','worker')
248
+ return None
249
+ row=self._row(conn,operation_id)
250
+ if row['approved_by']!=initial['approved_by']:raise Conflict('Reload the current approval identity')
251
+ self._contract(row,result=True)
252
+ live=conn.execute('SELECT %s::timestamptz>clock_timestamp() AS live',(row['lease_until'],)).fetchone()['live']
253
+ if row['state']=='dispatching'and live:return None
254
+ if row['state']not in {'approved','unknown','dispatching'}:return None
255
+ # An expired worker may have completed its network side effect. Do not
256
+ # infer that an expired lease means the external action never happened.
257
+ if row['state']in {'unknown','dispatching'}and not verified_idempotent_replay:return None
258
+ if row['approved_hash']!=self._fingerprint(row):raise Conflict('Approved payload no longer matches its immutable snapshot')
259
+ if row['attempts']>=self.max_attempts:
260
+ conn.execute("UPDATE workflow.operations SET state='dead',lease_token=NULL,lease_until=NULL WHERE id=%s",(row['id'],));self._event(conn,row,'dead','worker',{'reason':'dispatch_attempts_exhausted'});return None
261
+ if row['state']=='dispatching':
262
+ # An expired prior send may already have acted. Persist that fact
263
+ # before another idempotent attempt, even when recovery has not
264
+ # yet emitted its own interruption event.
265
+ self._event(conn,row,'outcome_unknown','worker',{'reason':'worker_interrupted'})
266
+ return self._lease(conn,row,'dispatching','dispatch_claimed')
267
+ def record_sent(self,operation_id,token,receipt):
268
+ canonical(receipt,1500)
269
+ with self.connect()as conn:
270
+ row=self._row(conn,operation_id);self._check_lease(conn,row,token,'dispatching')
271
+ updated=conn.execute("UPDATE workflow.operations SET state='sent',receipt=%s,lease_token=NULL,lease_until=NULL,updated_at=clock_timestamp() WHERE id=%s RETURNING *",(stored_json(receipt),row['id'])).fetchone();self._event(conn,updated,'sent','worker',{'payloadSha256':row['approved_hash']});return updated
272
+ def recover_expired(self,*,limit=50):
273
+ """Owned worker reconciliation, independent of a queue notification's fate.
274
+
275
+ Crash recovery never resets attempt counts or assumes a lost network
276
+ response means an action did not happen. Upstream stalled-job recovery is
277
+ also required to release the queue's abandoned execution locks.
278
+ """
279
+ if type(limit)is not int or not 1<=limit<=100:raise ValueError('Invalid recovery batch')
280
+ recovered=[]
281
+ with self.connect()as conn:
282
+ rows=conn.execute("SELECT * FROM workflow.operations WHERE workflow_key=%s AND state IN ('processing','dispatching') AND lease_until<=clock_timestamp() ORDER BY lease_until FOR UPDATE SKIP LOCKED LIMIT %s",(self.workflow_key,limit)).fetchall()
283
+ for row in rows:
284
+ state='unknown'if row['state']=='dispatching'else'dead'if row['attempts']>=self.max_attempts else'pending'
285
+ job=self._enqueue(conn,'extract',row['id'])if state=='pending'else row['queue_job_id']
286
+ conn.execute('UPDATE workflow.operations SET state=%s,execution_epoch=execution_epoch+1,lease_token=NULL,lease_until=NULL,queue_job_id=%s,updated_at=clock_timestamp() WHERE id=%s',(state,job,row['id']))
287
+ self._event(conn,row,'outcome_unknown'if state=='unknown'else'dead'if state=='dead'else'retry_pending','recovery',{'reason':'worker_interrupted'});recovered.append(str(row['id']))
288
+ return recovered
289
+ def reconcile_notifications(self,*,limit=50):
290
+ """Resume a safe pre-execution state whose queue notification was lost.
291
+
292
+ A queue failure before a domain lease must not strand a pending invoice.
293
+ Unknown external outcomes are deliberately excluded. This does not reset
294
+ business attempt limits, approval identity, payload or destination.
295
+ """
296
+ if type(limit)is not int or not 1<=limit<=100:raise ValueError('Invalid reconciliation batch')
297
+ repaired=[]
298
+ with self.connect()as conn:
299
+ rows=conn.execute("SELECT o.* FROM workflow.operations o WHERE workflow_key=%s AND state IN ('pending','approved') AND NOT EXISTS(SELECT 1 FROM workflow.procrastinate_jobs j WHERE j.task_name=CASE WHEN o.state='pending' THEN %s ELSE %s END AND j.args->>'operation_id'=o.id::text AND j.status IN ('todo','doing')) ORDER BY updated_at FOR UPDATE OF o SKIP LOCKED LIMIT %s",(self.workflow_key,self.tasks['extract'].name,self.tasks['dispatch'].name,limit)).fetchall()
300
+ for row in rows:
301
+ kind='extract'if row['state']=='pending'else'dispatch';task=self.tasks[kind]
302
+ # Recheck after the row lock: another reconciler may have committed
303
+ # a notification after the selecting statement's MVCC snapshot.
304
+ active=conn.execute("SELECT 1 FROM workflow.procrastinate_jobs WHERE task_name=%s AND args->>'operation_id'=%s AND status IN ('todo','doing') LIMIT 1",(task.name,str(row['id']))).fetchone()
305
+ if active:continue
306
+ job=self._enqueue(conn,kind,row['id']);conn.execute('UPDATE workflow.operations SET queue_job_id=%s,updated_at=clock_timestamp()WHERE id=%s',(job,row['id']));self._event(conn,row,'retry_pending','recovery',{'reason':'queue_notification_interrupted'});repaired.append(str(row['id']))
307
+ return repaired
308
+ def fail(self,operation_id,token,reason,*,retryable=False,ambiguous=True):
309
+ if type(retryable)is not bool or type(ambiguous)is not bool:raise ValueError('Explicit worker failure decisions are required')
310
+ if reason not in {'source_unavailable','invalid_result','model_unavailable','destination_unavailable','destination_rejected','worker_interrupted'}:raise ValueError('Use an owned error category, never raw provider/input text')
311
+ with self.connect()as conn:
312
+ row=self._row(conn,operation_id)
313
+ if row['state']not in {'processing','dispatching'}:raise LostLease('Operation is not executing')
314
+ self._check_lease(conn,row,token,row['state'])
315
+ previously_uncertain=row['state']=='dispatching'and conn.execute("SELECT EXISTS(SELECT 1 FROM workflow.events WHERE operation_id=%s AND account_id=%s AND event='outcome_unknown')AS uncertain",(row['id'],row['account_id'])).fetchone()['uncertain']
316
+ # A new attempt that sent nothing cannot disprove an older attempt's
317
+ # external effect. Keep uncertainty monotonic until a confirmed
318
+ # receipt or explicit operator reconciliation exists.
319
+ state='unknown'if row['state']=='dispatching'and(ambiguous or previously_uncertain)else ('pending'if row['state']=='processing'else'approved')if retryable and row['attempts']<self.max_attempts else'dead'
320
+ updated=conn.execute('UPDATE workflow.operations SET state=%s,lease_token=NULL,lease_until=NULL,updated_at=clock_timestamp() WHERE id=%s RETURNING *',(state,row['id'])).fetchone();self._event(conn,updated,'outcome_unknown'if state=='unknown'else'dead'if state=='dead'else'retry_pending','worker',{'reason':reason});return updated
321
+ def recover_extraction(self,actor,operation_id):
322
+ with self.connect()as conn:
323
+ self._actor(conn,actor,{'supervisor','owner'});row=self._row(conn,operation_id,actor.account_id)
324
+ if row['state']!='dead' or row['approved_hash']:raise Conflict('Only a failed pre-approval extraction can be explicitly recovered here')
325
+ job=self._enqueue(conn,'extract',row['id']);updated=conn.execute("UPDATE workflow.operations SET state='pending',attempts=0,execution_epoch=execution_epoch+1,lease_token=NULL,lease_until=NULL,queue_job_id=%s,updated_at=clock_timestamp() WHERE id=%s RETURNING *",(job,row['id'])).fetchone();self._event(conn,updated,'recovered',actor.subject);return updated
@@ -0,0 +1,110 @@
1
+ {
2
+ "format": "enterprise-application-files-v1",
3
+ "files": [
4
+ "enterprise_identity.py",
5
+ "enterprise_sources.py",
6
+ "enterprise_knowledge.py",
7
+ "enterprise_auth_store.py",
8
+ "enterprise_auth_schema.sql",
9
+ "enterprise_oauth.py",
10
+ "enterprise_sessions.py",
11
+ "enterprise_http.py",
12
+ "enterprise_web.py",
13
+ "enterprise_queries.py",
14
+ "enterprise_queries_schema.sql",
15
+ "enterprise_query_service.py",
16
+ "enterprise_audit.py",
17
+ "enterprise_audit_schema.sql",
18
+ "enterprise_models.py",
19
+ "enterprise_secrets.py",
20
+ "enterprise_configuration.py",
21
+ "enterprise_native.py",
22
+ "enterprise_worker.py",
23
+ "enterprise_operator.py",
24
+ "workflow_connection.py",
25
+ "workflow_errors.py",
26
+ "enterprise_google_jobs.py",
27
+ "enterprise_google_transfer.py",
28
+ "enterprise-aws-task-template.json",
29
+ "enterprise_aws_jobs.py",
30
+ "enterprise_aws_objects.py",
31
+ "enterprise_aws_transfer.py",
32
+ "enterprise_aws_hosts.py",
33
+ "enterprise_aws_host_probe.py",
34
+ "enterprise_document_jobs.py",
35
+ "enterprise_document_jobs_schema.sql",
36
+ "aws_json_model.py",
37
+ "azure_structured.py",
38
+ "gcp_structured.py",
39
+ "ibm_structured.py",
40
+ "structured_output.py",
41
+ "structured_http.py",
42
+ "policy_review.py",
43
+ "enterprise_extraction_cache.py",
44
+ "enterprise_extraction_schema.sql",
45
+ "enterprise_parser_transport.py",
46
+ "enterprise_document_contract.py",
47
+ "enterprise_document_job.py",
48
+ "public_faq.py",
49
+ "faq-output-contract.json",
50
+ "enterprise-web.html",
51
+ "enterprise-web-app.js",
52
+ "enterprise-web.css",
53
+ "enterprise-web-notices.txt",
54
+ "enterprise-web-lock.json"
55
+ ],
56
+ "providerFiles": {
57
+ "aws": [
58
+ "rds-global-ca.pem",
59
+ "rds-ca-source.json"
60
+ ],
61
+ "azure": [],
62
+ "gcp": [],
63
+ "ibm": []
64
+ },
65
+ "entrypoints": {
66
+ "api": [
67
+ "python",
68
+ "-I",
69
+ "/app/enterprise_native.py",
70
+ "api"
71
+ ],
72
+ "worker": [
73
+ "python",
74
+ "-I",
75
+ "/app/enterprise_worker.py"
76
+ ],
77
+ "operator": [
78
+ "python",
79
+ "-I",
80
+ "/app/enterprise_operator.py"
81
+ ]
82
+ },
83
+ "nativeDocumentWorkerProviders": [
84
+ "aws",
85
+ "gcp"
86
+ ],
87
+ "scope": "Application source inventory and owned entrypoints; not whole-project, native account or deployment acceptance.",
88
+ "parserFiles": [
89
+ "enterprise_document_contract.py",
90
+ "EnterpriseDocument.java",
91
+ "enterprise_document.py",
92
+ "enterprise_document_cli.py",
93
+ "enterprise_document_job.py",
94
+ "enterprise_parser_service.py",
95
+ "enterprise-document.Dockerfile",
96
+ "enterprise-document-lock.json"
97
+ ],
98
+ "pdfParserFiles": [
99
+ "invoice_document.py",
100
+ "invoice_extraction.py",
101
+ "structured_output.py",
102
+ "invoice_parser_cli.py",
103
+ "invoice_parser_service.py",
104
+ "invoice_parser_identity.py",
105
+ "parser-requirements.lock",
106
+ "invoice-parser-python-lock.json",
107
+ "invoice-parser-lock.json",
108
+ "invoice-parser.Dockerfile"
109
+ ]
110
+ }