@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.
- package/CONSTITUTION.md +144 -0
- package/README.md +33 -2
- package/agent-skills/discovery/SKILL.md +48 -0
- package/agent-skills/discovery/topics.json +139 -0
- package/agent-skills/generation-capabilities.json +760 -0
- package/agent-skills/service-lifecycle.json +21 -0
- package/agent-skills/specialists/architecture/SKILL.md +15 -0
- package/agent-skills/specialists/aws/SKILL.md +17 -0
- package/agent-skills/specialists/azure/SKILL.md +7 -0
- package/agent-skills/specialists/composition/SKILL.md +17 -0
- package/agent-skills/specialists/devops/SKILL.md +10 -0
- package/agent-skills/specialists/finops/SKILL.md +7 -0
- package/agent-skills/specialists/gcp/SKILL.md +7 -0
- package/agent-skills/specialists/ibm/SKILL.md +7 -0
- package/agent-skills/specialists/manifest.json +13 -0
- package/agent-skills/specialists/pulumi/SKILL.md +7 -0
- package/agent-skills/specialists/security/SKILL.md +7 -0
- package/agent-skills/specialists/terraform/SKILL.md +14 -0
- package/agent-skills/upstream/aws/LICENSE +175 -0
- package/agent-skills/upstream/aws/SKILL.md +125 -0
- package/agent-skills/upstream/azure/LICENSE +21 -0
- package/agent-skills/upstream/azure/SKILL.md +387 -0
- package/agent-skills/upstream/gcp/LICENSE +202 -0
- package/agent-skills/upstream/gcp/SKILL.md +159 -0
- package/agent-skills/upstream/manifest.json +57 -0
- package/agent-skills/upstream/pulumi/LICENSE +201 -0
- package/agent-skills/upstream/pulumi/SKILL.md +501 -0
- package/agent-skills/upstream/terraform/LICENSE +373 -0
- package/agent-skills/upstream/terraform/SKILL.md +316 -0
- package/agent-skills/workflows/workflows.json +601 -0
- package/cli/architect.mjs +3 -0
- package/cli/runtime.mjs +115 -0
- package/dist/assets/html2canvas.esm-QH1iLAAe.js +22 -0
- package/dist/assets/index-B97MkVMs.css +1 -0
- package/dist/assets/index-qtCM2D7O.js +21271 -0
- package/dist/assets/index.es-C6C0sneB.js +18 -0
- package/dist/assets/purify.es-CAi2OJFm.js +3 -0
- package/dist/assets/visual-export-DjbjgQbA.js +173 -0
- package/dist/favicon.svg +2 -0
- package/dist/fonts/DM-Sans-OFL.txt +93 -0
- package/dist/fonts/Manrope-OFL.txt +93 -0
- package/dist/fonts/NotoSans-Regular.ttf +0 -0
- package/dist/fonts/OFL.txt +94 -0
- package/dist/fonts/dm-sans-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/manrope-latin-wght-normal.woff2 +0 -0
- package/dist/index.html +4 -0
- package/dist/licenses/aws-architect-LICENSE.txt +17 -0
- package/dist/licenses/aws-mcp-LICENSE.txt +175 -0
- package/dist/licenses/aws-mcp-NOTICE.txt +1 -0
- package/dist/licenses/cloud-emulation-notices.txt +36619 -0
- package/dist/licenses/dependency-notices.txt +6379 -0
- package/dist/licenses/emulation-notices.txt +717 -0
- package/dist/licenses/github-copilot-sdk-LICENSE.txt +21 -0
- package/dist/licenses/memory-dependency-notices.txt +3319 -0
- package/dist/licenses/openarchflow-LICENSE.txt +21 -0
- package/dist/licenses/python-dependency-notices.txt +11951 -0
- package/docs/upstream-lock.json +26 -0
- package/knowledge/engineering-practices.json +536 -0
- package/package.json +30 -4
- package/packaging/uv-release-lock.json +54 -0
- package/public/licenses/aws-architect-LICENSE.txt +17 -0
- package/public/licenses/aws-mcp-LICENSE.txt +175 -0
- package/public/licenses/aws-mcp-NOTICE.txt +1 -0
- package/public/licenses/cloud-emulation-notices.txt +36619 -0
- package/public/licenses/dependency-notices.txt +6379 -0
- package/public/licenses/emulation-notices.txt +717 -0
- package/public/licenses/github-copilot-sdk-LICENSE.txt +21 -0
- package/public/licenses/memory-dependency-notices.txt +3319 -0
- package/public/licenses/openarchflow-LICENSE.txt +21 -0
- package/public/licenses/python-dependency-notices.txt +11951 -0
- package/scripts/terraform-render.mjs +8 -0
- package/server/__init__.py +0 -0
- package/server/abstraction.py +28 -0
- package/server/agent_runtime.py +153 -0
- package/server/app.py +257 -0
- package/server/architect.py +112 -0
- package/server/architecture_activity.py +67 -0
- package/server/attachments.py +101 -0
- package/server/cloud-emulation-requirements.txt +29 -0
- package/server/codex_app_server.py +219 -0
- package/server/codex_engineering_backend.py +266 -0
- package/server/codex_worker_policy.py +170 -0
- package/server/contracts.py +315 -0
- package/server/copilot_worker.py +16 -0
- package/server/dependency_mirror.py +54 -0
- package/server/design_patch.py +43 -0
- package/server/emulation-requirements.txt +8 -0
- package/server/emulation_adapters.py +20 -0
- package/server/emulation_routes.py +98 -0
- package/server/emulation_worker.py +351 -0
- package/server/engineering_artifacts.py +215 -0
- package/server/engineering_assets/application-runtime.json +4372 -0
- package/server/engineering_assets/architecture_work.schema.json +79 -0
- package/server/engineering_assets/materialize_runtime.py +62 -0
- package/server/engineering_assets/prepare_tools.py +96 -0
- package/server/engineering_assets/sql_validation.py +59 -0
- package/server/engineering_contexts.py +120 -0
- package/server/engineering_delivery.py +210 -0
- package/server/engineering_finalization.py +210 -0
- package/server/engineering_handoff.py +163 -0
- package/server/engineering_jobs.py +206 -0
- package/server/engineering_knowledge.py +75 -0
- package/server/engineering_reconciliation.py +159 -0
- package/server/engineering_routes.py +469 -0
- package/server/engineering_sessions.py +273 -0
- package/server/engineering_tools.py +166 -0
- package/server/generation_lint.py +18 -0
- package/server/local_providers.py +181 -0
- package/server/local_validation.py +236 -0
- package/server/memory-requirements.lock +181 -0
- package/server/memory-requirements.txt +6 -0
- package/server/memory_routes.py +82 -0
- package/server/memory_service.py +273 -0
- package/server/memory_worker.py +66 -0
- package/server/openai_voice.py +80 -0
- package/server/packaged_app.py +9 -0
- package/server/pricing.py +84 -0
- package/server/process_control_observation.py +31 -0
- package/server/prompts.py +123 -0
- package/server/public_faq_emulation_worker.py +44 -0
- package/server/requirements.lock +1618 -0
- package/server/requirements.txt +68 -0
- package/server/runtime_dependency_locks.py +27 -0
- package/server/runtime_evidence.py +93 -0
- package/server/settings.py +14 -0
- package/server/skills.py +103 -0
- package/server/storage_emulation_worker.py +160 -0
- package/server/structured_emulation_worker.py +48 -0
- package/server/terraform_routes.py +118 -0
- package/server/upstream/__init__.py +0 -0
- package/server/upstream/agent/__init__.py +1 -0
- package/server/upstream/agent/aws_architect.py +600 -0
- package/server/upstream/agent/config/__init__.py +1 -0
- package/server/upstream/agent/config/agent_config.py +82 -0
- package/server/upstream/agent/config/prompts.py +138 -0
- package/server/upstream/agent/rate_limiter.py +62 -0
- package/server/upstream/utils/__init__.py +1 -0
- package/server/upstream/utils/file_writer.py +43 -0
- package/server/validation_applicability.py +85 -0
- package/server/validation_jobs.py +252 -0
- package/server/validation_workers.py +48 -0
- package/server/voice_routes.py +91 -0
- package/server/voice_worker.py +26 -0
- package/specs/028-convergence-evaluation/evidence/20261110-ibm-invoice-native/registry-structured/qualification.json +72 -0
- package/specs/028-convergence-evaluation/evidence/20261110-invoice-runtime/durable-current/receipt.json +61 -0
- package/specs/029-general-purpose-engine/evidence/20261111-runtime-dependencies/sdk/receipt.json +22 -0
- package/src/ArchitectureActivity.jsx +54 -0
- package/src/ArchitectureWorkPanel.jsx +46 -0
- package/src/ArtifactChecks.jsx +49 -0
- package/src/BlockRequirements.jsx +13 -0
- package/src/BrainActivity.jsx +11 -0
- package/src/ChatMessage.jsx +19 -0
- package/src/ChatResizeHandle.jsx +6 -0
- package/src/CodePreview.jsx +8 -0
- package/src/ComponentReview.jsx +31 -0
- package/src/DeliveryViews.jsx +59 -0
- package/src/EmulationPanel.jsx +44 -0
- package/src/EngagementViews.jsx +385 -0
- package/src/EngineeringPanel.jsx +151 -0
- package/src/ImplementationDelivery.jsx +55 -0
- package/src/JourneyViews.jsx +400 -0
- package/src/MemoryPanel.jsx +46 -0
- package/src/OpenAIVoicePanel.jsx +65 -0
- package/src/OutputsView.jsx +65 -0
- package/src/TerraformView.jsx +57 -0
- package/src/WorkbenchDialogs.jsx +532 -0
- package/src/activity-presentation.mjs +28 -0
- package/src/ai-qualification-scenarios.mjs +31 -0
- package/src/approval-application-files.mjs +32 -0
- package/src/approval-applications.mjs +82 -0
- package/src/approval-spec-kit.mjs +30 -0
- package/src/architecture-activity.css +28 -0
- package/src/architecture-activity.mjs +63 -0
- package/src/architecture-work.mjs +176 -0
- package/src/artifact-work.mjs +103 -0
- package/src/async-documents.mjs +191 -0
- package/src/atflow.css +1140 -0
- package/src/atforma.css +748 -0
- package/src/atmem-tokens.css +79 -0
- package/src/aws-preflight.mjs +60 -0
- package/src/aws-public-faq.mjs +102 -0
- package/src/aws-validation-scenarios.mjs +10 -0
- package/src/aws-validation.mjs +48 -0
- package/src/azure-plan-mocks.mjs +25 -0
- package/src/azure-structured.mjs +133 -0
- package/src/bedrock-summary.mjs +152 -0
- package/src/bounded-rag.mjs +60 -0
- package/src/brand.css +9 -0
- package/src/canvas-view.mjs +28 -0
- package/src/capability-composition.mjs +44 -0
- package/src/chat-attachments.mjs +13 -0
- package/src/cloud-provider-locks.mjs +9 -0
- package/src/cloud-storage-scenarios.mjs +2 -0
- package/src/component-review.mjs +55 -0
- package/src/composition-spec-kit.mjs +30 -0
- package/src/consultation-context.mjs +15 -0
- package/src/consultation.mjs +52 -0
- package/src/container-contracts.mjs +5 -0
- package/src/container-inspection.mjs +75 -0
- package/src/container-runtime.mjs +30 -0
- package/src/container-security-inspection.mjs +49 -0
- package/src/container-terraform.mjs +109 -0
- package/src/conversation.mjs +17 -0
- package/src/core.mjs +863 -0
- package/src/cross-cloud-storage.mjs +100 -0
- package/src/delivery-capabilities.mjs +25 -0
- package/src/delivery.mjs +58 -0
- package/src/deployment-ownership.mjs +10 -0
- package/src/deployment-region.mjs +11 -0
- package/src/derive.mjs +31 -0
- package/src/design-build-flow.mjs +10 -0
- package/src/diagram-attention.mjs +24 -0
- package/src/discovery.mjs +359 -0
- package/src/document.mjs +170 -0
- package/src/emulation-feedback.mjs +61 -0
- package/src/emulation-guidance.mjs +37 -0
- package/src/engagement.mjs +274 -0
- package/src/engineering-client.mjs +73 -0
- package/src/engineering-defaults.mjs +17 -0
- package/src/engineering.css +31 -0
- package/src/enterprise-application.mjs +76 -0
- package/src/enterprise-aws-host-infrastructure.mjs +62 -0
- package/src/enterprise-aws-host-tests.mjs +15 -0
- package/src/enterprise-aws-infrastructure-tests.mjs +38 -0
- package/src/enterprise-aws-infrastructure.mjs +138 -0
- package/src/enterprise-google-infrastructure.mjs +84 -0
- package/src/enterprise-google-tests.mjs +25 -0
- package/src/estimate.mjs +188 -0
- package/src/existing-references.mjs +18 -0
- package/src/external-identities.mjs +17 -0
- package/src/faq-lambda-build.mjs +28 -0
- package/src/gcp-structured.mjs +104 -0
- package/src/generation-provider.mjs +7 -0
- package/src/generation-quality.mjs +69 -0
- package/src/handoff.mjs +141 -0
- package/src/ibm-registry.mjs +12 -0
- package/src/ibm-structured.mjs +103 -0
- package/src/identifiers.mjs +15 -0
- package/src/implementation-map.mjs +14 -0
- package/src/implementation-outcome.mjs +8 -0
- package/src/incomplete-terraform.mjs +9 -0
- package/src/integrations.ts +137 -0
- package/src/interface-contracts.mjs +30 -0
- package/src/invoice-application.mjs +66 -0
- package/src/invoice-aws-operations.mjs +136 -0
- package/src/invoice-aws.mjs +143 -0
- package/src/invoice-azure-operations.mjs +147 -0
- package/src/invoice-azure.mjs +134 -0
- package/src/invoice-builder.mjs +35 -0
- package/src/invoice-dependencies.mjs +43 -0
- package/src/invoice-gcp-operations.mjs +178 -0
- package/src/invoice-gcp.mjs +104 -0
- package/src/invoice-ibm-operations.mjs +278 -0
- package/src/invoice-ibm.mjs +142 -0
- package/src/invoice-operations.mjs +143 -0
- package/src/invoice-plan.mjs +45 -0
- package/src/invoice-region.mjs +6 -0
- package/src/invoice-spec-kit.mjs +61 -0
- package/src/invoice-state.mjs +7 -0
- package/src/invoice-terraform.mjs +29 -0
- package/src/invoice-tests.mjs +122 -0
- package/src/journey-workspace.css +72 -0
- package/src/journey.mjs +87 -0
- package/src/levels.mjs +145 -0
- package/src/local-agent.mjs +184 -0
- package/src/main.jsx +2458 -0
- package/src/model-policy-preflight.mjs +34 -0
- package/src/openai-voice.mjs +102 -0
- package/src/output-bundle.mjs +11 -0
- package/src/ownership-inspection.mjs +28 -0
- package/src/pack.mjs +201 -0
- package/src/pricing.mjs +31 -0
- package/src/production-state.mjs +8 -0
- package/src/project-copy.mjs +10 -0
- package/src/project-file.mjs +160 -0
- package/src/project-links.mjs +3 -0
- package/src/protected-state.mjs +43 -0
- package/src/public-faq-builder.mjs +19 -0
- package/src/public-faq-clouds.mjs +251 -0
- package/src/public-faq.mjs +122 -0
- package/src/pulumi.mjs +123 -0
- package/src/python-container.mjs +25 -0
- package/src/python-runtime.mjs +50 -0
- package/src/rag-handler.mjs +43 -0
- package/src/rag-web-assets.mjs +52 -0
- package/src/rag-web.mjs +68 -0
- package/src/records.mjs +177 -0
- package/src/resources.mjs +163 -0
- package/src/review.mjs +252 -0
- package/src/runtime/EnterpriseDocument.java +89 -0
- package/src/runtime/approved_http_destination.py +72 -0
- package/src/runtime/aws-lambda-qualification-lock.json +7 -0
- package/src/runtime/aws-python-lock.json +82 -0
- package/src/runtime/aws-web-python-lock.json +887 -0
- package/src/runtime/aws_json_model.py +42 -0
- package/src/runtime/azure-python-lock.json +863 -0
- package/src/runtime/azure-sources.json +8 -0
- package/src/runtime/azure-test-lock.json +23 -0
- package/src/runtime/azure_acceptance.py +192 -0
- package/src/runtime/azure_structured.py +153 -0
- package/src/runtime/bounded_rag.py +126 -0
- package/src/runtime/catalog_admin.py +70 -0
- package/src/runtime/cloud-sql-proxy-lock.json +8 -0
- package/src/runtime/cloud-sql-proxy-security-review.json +30 -0
- package/src/runtime/connector_cli.py +50 -0
- package/src/runtime/connector_sync.py +70 -0
- package/src/runtime/durable-python-lock.json +247 -0
- package/src/runtime/durable_workflow.py +325 -0
- package/src/runtime/enterprise-application-manifest.json +110 -0
- package/src/runtime/enterprise-application-sources.json +266 -0
- package/src/runtime/enterprise-auth-python-lock.json +592 -0
- package/src/runtime/enterprise-aws-host-bootstrap-source.json +1 -0
- package/src/runtime/enterprise-aws-host-probe-source.json +1 -0
- package/src/runtime/enterprise-aws-task-template.json +235 -0
- package/src/runtime/enterprise-document-lock.json +18 -0
- package/src/runtime/enterprise-document.Dockerfile +15 -0
- package/src/runtime/enterprise-runtime-aws-python-lock.json +1115 -0
- package/src/runtime/enterprise-runtime-azure-python-lock.json +1106 -0
- package/src/runtime/enterprise-runtime-gcp-python-lock.json +1060 -0
- package/src/runtime/enterprise-runtime-ibm-python-lock.json +1096 -0
- package/src/runtime/enterprise-runtime-python-lock.json +1058 -0
- package/src/runtime/enterprise-runtime.Dockerfile +15 -0
- package/src/runtime/enterprise-web-app.js +1 -0
- package/src/runtime/enterprise-web-entry.js +105 -0
- package/src/runtime/enterprise-web-lock.json +29 -0
- package/src/runtime/enterprise-web-notices.txt +229 -0
- package/src/runtime/enterprise-web.css +4 -0
- package/src/runtime/enterprise-web.html +8 -0
- package/src/runtime/enterprise_audit.py +91 -0
- package/src/runtime/enterprise_audit_schema.sql +25 -0
- package/src/runtime/enterprise_auth_schema.sql +67 -0
- package/src/runtime/enterprise_auth_store.py +241 -0
- package/src/runtime/enterprise_aws_host_bootstrap.py +120 -0
- package/src/runtime/enterprise_aws_host_probe.py +105 -0
- package/src/runtime/enterprise_aws_hosts.py +136 -0
- package/src/runtime/enterprise_aws_jobs.py +300 -0
- package/src/runtime/enterprise_aws_objects.py +93 -0
- package/src/runtime/enterprise_aws_transfer.py +83 -0
- package/src/runtime/enterprise_azure_batch_api.py +128 -0
- package/src/runtime/enterprise_azure_host.py +599 -0
- package/src/runtime/enterprise_azure_jobs.py +294 -0
- package/src/runtime/enterprise_azure_objects.py +234 -0
- package/src/runtime/enterprise_azure_pool.py +161 -0
- package/src/runtime/enterprise_azure_transfer.py +122 -0
- package/src/runtime/enterprise_configuration.py +136 -0
- package/src/runtime/enterprise_document.py +116 -0
- package/src/runtime/enterprise_document_cli.py +32 -0
- package/src/runtime/enterprise_document_contract.py +54 -0
- package/src/runtime/enterprise_document_job.py +109 -0
- package/src/runtime/enterprise_document_jobs.py +122 -0
- package/src/runtime/enterprise_document_jobs_schema.sql +23 -0
- package/src/runtime/enterprise_extraction_cache.py +186 -0
- package/src/runtime/enterprise_extraction_schema.sql +17 -0
- package/src/runtime/enterprise_google_jobs.py +275 -0
- package/src/runtime/enterprise_google_transfer.py +85 -0
- package/src/runtime/enterprise_http.py +212 -0
- package/src/runtime/enterprise_identity.py +52 -0
- package/src/runtime/enterprise_knowledge.py +152 -0
- package/src/runtime/enterprise_models.py +94 -0
- package/src/runtime/enterprise_native.py +181 -0
- package/src/runtime/enterprise_oauth.py +132 -0
- package/src/runtime/enterprise_operator.py +160 -0
- package/src/runtime/enterprise_parser_service.py +136 -0
- package/src/runtime/enterprise_parser_transport.py +68 -0
- package/src/runtime/enterprise_queries.py +255 -0
- package/src/runtime/enterprise_queries_schema.sql +27 -0
- package/src/runtime/enterprise_query_service.py +111 -0
- package/src/runtime/enterprise_secrets.py +110 -0
- package/src/runtime/enterprise_sessions.py +95 -0
- package/src/runtime/enterprise_sources.py +260 -0
- package/src/runtime/enterprise_web.py +39 -0
- package/src/runtime/enterprise_worker.py +68 -0
- package/src/runtime/export_contract_acceptance.py +18 -0
- package/src/runtime/faq-output-contract.json +40 -0
- package/src/runtime/faq-web-app.js +41 -0
- package/src/runtime/faq-web.css +1 -0
- package/src/runtime/faq-web.html +6 -0
- package/src/runtime/gcp-sources.json +9 -0
- package/src/runtime/gcp_acceptance.py +110 -0
- package/src/runtime/gcp_structured.py +150 -0
- package/src/runtime/http_acceptance.py +39 -0
- package/src/runtime/iap-web-app.js +36 -0
- package/src/runtime/iap-web-source.json +1 -0
- package/src/runtime/ibm-python-lock.json +856 -0
- package/src/runtime/ibm-sources.json +9 -0
- package/src/runtime/ibm_acceptance.py +133 -0
- package/src/runtime/ibm_structured.py +113 -0
- package/src/runtime/invoice-azapi-provider-lock.json +7 -0
- package/src/runtime/invoice-ibm-provider-lock.json +7 -0
- package/src/runtime/invoice-parser-lock.json +1199 -0
- package/src/runtime/invoice-parser-python-lock.json +56 -0
- package/src/runtime/invoice-parser.Dockerfile +190 -0
- package/src/runtime/invoice-sources.json +58 -0
- package/src/runtime/invoice-test-sources.json +24 -0
- package/src/runtime/invoice-web.css +2 -0
- package/src/runtime/invoice-web.html +12 -0
- package/src/runtime/invoice-web.js +112 -0
- package/src/runtime/invoice_configuration.py +17 -0
- package/src/runtime/invoice_document.py +95 -0
- package/src/runtime/invoice_extraction.py +96 -0
- package/src/runtime/invoice_http.py +129 -0
- package/src/runtime/invoice_identity.py +5 -0
- package/src/runtime/invoice_maintenance.py +40 -0
- package/src/runtime/invoice_native.py +77 -0
- package/src/runtime/invoice_object_store.py +153 -0
- package/src/runtime/invoice_operations.py +108 -0
- package/src/runtime/invoice_operator.py +79 -0
- package/src/runtime/invoice_operator_core.py +39 -0
- package/src/runtime/invoice_operator_job.py +147 -0
- package/src/runtime/invoice_parser_cli.py +17 -0
- package/src/runtime/invoice_parser_identity.py +39 -0
- package/src/runtime/invoice_parser_service.py +89 -0
- package/src/runtime/invoice_parser_transport.py +89 -0
- package/src/runtime/invoice_processing.py +24 -0
- package/src/runtime/invoice_retention.py +16 -0
- package/src/runtime/invoice_runtime_secrets.py +43 -0
- package/src/runtime/invoice_stage.py +80 -0
- package/src/runtime/invoice_web.py +39 -0
- package/src/runtime/invoice_worker.py +50 -0
- package/src/runtime/lambda_faq.py +5 -0
- package/src/runtime/parser-requirements.lock +4 -0
- package/src/runtime/policy_review.py +18 -0
- package/src/runtime/postgres-qualification-lock.json +21 -0
- package/src/runtime/public-faq-sources.json +22 -0
- package/src/runtime/public_catalog_admin.py +122 -0
- package/src/runtime/public_catalog_store.py +125 -0
- package/src/runtime/public_faq.py +144 -0
- package/src/runtime/public_faq_app.py +49 -0
- package/src/runtime/python-container-lock.json +18 -0
- package/src/runtime/rag-sources.json +10 -0
- package/src/runtime/rag_acceptance.py +60 -0
- package/src/runtime/rag_aws_adapter.py +95 -0
- package/src/runtime/rds-ca-source.json +9 -0
- package/src/runtime/rds-global-ca.pem +2888 -0
- package/src/runtime/state-contract-check-source.json +4 -0
- package/src/runtime/state_contract_check.py +338 -0
- package/src/runtime/structured-source.json +1 -0
- package/src/runtime/structured-web-app.js +71 -0
- package/src/runtime/structured-web-source.json +1 -0
- package/src/runtime/structured_http.py +105 -0
- package/src/runtime/structured_output.py +48 -0
- package/src/runtime/web-python-lock.json +802 -0
- package/src/runtime/web_user_admin.py +44 -0
- package/src/runtime/workflow_application.py +62 -0
- package/src/runtime/workflow_bindings.py +128 -0
- package/src/runtime/workflow_configuration.py +40 -0
- package/src/runtime/workflow_connection.py +105 -0
- package/src/runtime/workflow_contract.py +54 -0
- package/src/runtime/workflow_database.py +94 -0
- package/src/runtime/workflow_errors.py +6 -0
- package/src/runtime/workflow_http.py +178 -0
- package/src/runtime/workflow_identity.py +69 -0
- package/src/runtime/workflow_payload.py +118 -0
- package/src/runtime/workflow_process_stage.py +88 -0
- package/src/runtime/workflow_profile.py +91 -0
- package/src/runtime/workflow_review.py +106 -0
- package/src/runtime/workflow_role_bootstrap.py +104 -0
- package/src/runtime/workflow_schema.sql +72 -0
- package/src/runtime/workflow_worker.py +142 -0
- package/src/runtime-settings.mjs +15 -0
- package/src/s3-access.mjs +14 -0
- package/src/source-contracts.mjs +17 -0
- package/src/spec-kit.mjs +186 -0
- package/src/state-custody.mjs +32 -0
- package/src/state-inspection.mjs +45 -0
- package/src/state-spec-kit.mjs +13 -0
- package/src/storage-tests.mjs +25 -0
- package/src/structured-api.mjs +133 -0
- package/src/structured-contract.mjs +19 -0
- package/src/structured-operation-policy.mjs +2 -0
- package/src/structured-web.mjs +17 -0
- package/src/style.css +1 -0
- package/src/system-description.mjs +26 -0
- package/src/terraform-admission.mjs +66 -0
- package/src/terraform-composition.mjs +83 -0
- package/src/terraform-expressions.mjs +46 -0
- package/src/terraform-validation-coverage.mjs +11 -0
- package/src/terraform.mjs +128 -0
- package/src/text-statistics.mjs +51 -0
- package/src/upstream/openarchflow/format-payload.ts +26 -0
- package/src/upstream/openarchflow/import/mermaid.ts +205 -0
- package/src/upstream/openarchflow/import/sql-ddl.ts +109 -0
- package/src/upstream/openarchflow/layout.ts +54 -0
- package/src/upstream/openarchflow/providers/aws.ts +196 -0
- package/src/upstream/openarchflow/providers/azure.ts +126 -0
- package/src/upstream/openarchflow/providers/cloudnative.ts +71 -0
- package/src/upstream/openarchflow/providers/generic.ts +227 -0
- package/src/upstream/openarchflow/providers/integration.ts +22 -0
- package/src/upstream/openarchflow/providers/types.ts +2 -0
- package/src/upstream/openarchflow/templates.ts +937 -0
- package/src/upstream-catalog.mjs +10 -0
- package/src/useChatScroll.jsx +36 -0
- package/src/useEmulation.jsx +36 -0
- package/src/validation-receipt.mjs +10 -0
- package/src/visual-export.mjs +92 -0
- package/src/voice-conversation.mjs +117 -0
- package/src/work-intake.mjs +24 -0
- package/src/workflow-runtime-inventory.mjs +3 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Private bounded PDF RPC container; never expose as an anonymous public service.
|
|
2
|
+
|
|
3
|
+
Hosting must restrict callers to the worker, isolate this container and grant it
|
|
4
|
+
no document-store, database, model or destination permissions. Provider ingress
|
|
5
|
+
auth/network/TLS is a separate infrastructure boundary, not an HTTP header trust
|
|
6
|
+
claim made by this server. No request selects a URL, file, command or credential.
|
|
7
|
+
"""
|
|
8
|
+
from http.server import BaseHTTPRequestHandler,ThreadingHTTPServer
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import socket
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
import threading
|
|
16
|
+
import time
|
|
17
|
+
sys.path.insert(0,str(Path(__file__).resolve().parent))
|
|
18
|
+
from invoice_document import PdfDocument,DocumentError
|
|
19
|
+
|
|
20
|
+
LIMIT=10000000
|
|
21
|
+
|
|
22
|
+
class ParserServer(ThreadingHTTPServer):
|
|
23
|
+
daemon_threads=True
|
|
24
|
+
request_queue_size=16
|
|
25
|
+
def __init__(self,address,parser,authorize=None):
|
|
26
|
+
if authorize is not None and not callable(authorize):raise ValueError('Use the owned parser authorization adapter')
|
|
27
|
+
self.parser=parser;self.authorize=authorize;self.slot=threading.BoundedSemaphore(1);super().__init__(address,ParserHandler)
|
|
28
|
+
|
|
29
|
+
class ParserHandler(BaseHTTPRequestHandler):
|
|
30
|
+
protocol_version='HTTP/1.0'
|
|
31
|
+
def log_message(self,*args):pass
|
|
32
|
+
def setup(self):
|
|
33
|
+
super().setup();self.connection.settimeout(5)
|
|
34
|
+
def reply(self,status,value):
|
|
35
|
+
body=json.dumps(value,ensure_ascii=False,allow_nan=False).encode('utf-8')
|
|
36
|
+
self.send_response(status);self.send_header('Content-Type','application/json');self.send_header('Content-Length',str(len(body)));self.send_header('Cache-Control','no-store');self.send_header('X-Content-Type-Options','nosniff');self.end_headers();self.wfile.write(body)
|
|
37
|
+
def do_GET(self):
|
|
38
|
+
if self.path=='/healthz':self.reply(200,{'status':'running'})
|
|
39
|
+
else:self.reply(404,{'status':'rejected','reason':'invalid_request'})
|
|
40
|
+
def do_POST(self):
|
|
41
|
+
if self.path!='/extract':self.reply(404,{'status':'rejected','reason':'invalid_request'});return
|
|
42
|
+
if self.server.authorize is not None:
|
|
43
|
+
try:
|
|
44
|
+
headers=self.headers.get_all('Authorization')or[]
|
|
45
|
+
if len(headers)!=1 or not headers[0].startswith('Bearer '):raise PermissionError()
|
|
46
|
+
self.server.authorize(headers[0][7:])
|
|
47
|
+
except Exception:self.reply(403,{'status':'rejected','reason':'access_denied'});return
|
|
48
|
+
# Reject ambiguous framing rather than trusting a proxy's normalization.
|
|
49
|
+
lengths=self.headers.get_all('Content-Length')or[]
|
|
50
|
+
if self.headers.get('Transfer-Encoding')or len(lengths)!=1 or not lengths[0].isascii()or not lengths[0].isdigit():self.reply(411,{'status':'rejected','reason':'invalid_request'});return
|
|
51
|
+
if len(lengths[0])>10 or not 1<=int(lengths[0])<=LIMIT:self.reply(413,{'status':'rejected','reason':'document_too_large'});return
|
|
52
|
+
if self.headers.get('Content-Type','').split(';')[0].lower()!='application/pdf':self.reply(415,{'status':'rejected','reason':'invalid_pdf'});return
|
|
53
|
+
if not self.server.slot.acquire(blocking=False):self.reply(429,{'status':'rejected','reason':'busy'});return
|
|
54
|
+
try:
|
|
55
|
+
remaining=int(lengths[0]);body=bytearray();deadline=time.monotonic()+15
|
|
56
|
+
while remaining:
|
|
57
|
+
left=deadline-time.monotonic()
|
|
58
|
+
if left<=0:raise TimeoutError()
|
|
59
|
+
self.connection.settimeout(min(5,left));chunk=self.rfile.read1(min(remaining,65536))
|
|
60
|
+
if not chunk:raise ValueError('Incomplete PDF body')
|
|
61
|
+
body.extend(chunk);remaining-=len(chunk)
|
|
62
|
+
raw=bytes(body);self.connection.settimeout(5)
|
|
63
|
+
document=self.server.parser.extract(raw,hashlib.sha256(raw).hexdigest())
|
|
64
|
+
self.reply(200,{'status':'ok','document':document})
|
|
65
|
+
except DocumentError as error:self.reply(422,{'status':'rejected','reason':error.code})
|
|
66
|
+
except(TimeoutError,socket.timeout):self.reply(408,{'status':'rejected','reason':'upload_timeout'})
|
|
67
|
+
except ValueError:self.reply(400,{'status':'rejected','reason':'invalid_request'})
|
|
68
|
+
except Exception:self.reply(503,{'status':'rejected','reason':'extraction_unavailable'})
|
|
69
|
+
finally:self.server.slot.release()
|
|
70
|
+
|
|
71
|
+
def main():
|
|
72
|
+
# These checks catch common accidental mounts. Infrastructure admission still
|
|
73
|
+
# must prove that this separate workload has no inherited cloud authority.
|
|
74
|
+
forbidden=['DATABASE_PASSWORD','DATABASE_PASSWORD_FILE','DATABASE_HOST','DATABASE_CONNECTION_NAME','DESTINATION_TOKEN_FILE','DESTINATION_ENDPOINT','GOOGLE_APPLICATION_CREDENTIALS','AWS_ACCESS_KEY_ID','AWS_SECRET_ACCESS_KEY','AWS_CONTAINER_CREDENTIALS_RELATIVE_URI','AWS_CONTAINER_CREDENTIALS_FULL_URI','IDENTITY_ENDPOINT','IDENTITY_HEADER','MSI_ENDPOINT','MSI_SECRET']
|
|
75
|
+
if any(os.environ.get(key)for key in forbidden)or Path('/var/run/secrets/codeengine.cloud.ibm.com/compute-resource-token/token').exists():raise ValueError('Do not supply parser database, action or workload credentials')
|
|
76
|
+
port=int(os.environ.get('PORT','8080'))
|
|
77
|
+
if not 1024<=port<=65535:raise ValueError('Use the owned nonprivileged parser port')
|
|
78
|
+
mode=os.environ.get('PARSER_AUTH_MODE','private-ingress');authorize=None
|
|
79
|
+
if mode=='entra-workload':
|
|
80
|
+
from invoice_parser_identity import EntraParserVerifier
|
|
81
|
+
authorize=EntraParserVerifier(*[os.environ[name]for name in ['PARSER_TENANT_ID','PARSER_AUDIENCE','PARSER_WORKER_CLIENT_ID','PARSER_WORKER_PRINCIPAL_ID']])
|
|
82
|
+
elif mode=='shared-token':
|
|
83
|
+
from invoice_parser_identity import SharedParserVerifier
|
|
84
|
+
authorize=SharedParserVerifier(os.environ.pop('PARSER_SHARED_TOKEN',''))
|
|
85
|
+
elif mode!='private-ingress':raise ValueError('Use the owned parser authorization mode')
|
|
86
|
+
elif 'PARSER_SHARED_TOKEN'in os.environ:raise ValueError('Parser token requires explicit authenticated mode')
|
|
87
|
+
ParserServer(('0.0.0.0',port),PdfDocument(),authorize).serve_forever(poll_interval=.2)
|
|
88
|
+
|
|
89
|
+
if __name__=='__main__':main()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Worker-only private HTTPS parser contract. Endpoint/auth are operator-owned."""
|
|
2
|
+
import json
|
|
3
|
+
import re
|
|
4
|
+
import time
|
|
5
|
+
from urllib.parse import urlsplit
|
|
6
|
+
import requests
|
|
7
|
+
from invoice_document import DocumentError
|
|
8
|
+
from invoice_extraction import document_evidence
|
|
9
|
+
from invoice_object_store import digest_pdf
|
|
10
|
+
from structured_output import _object
|
|
11
|
+
from workflow_errors import TemporaryWork
|
|
12
|
+
|
|
13
|
+
class ParserClient:
|
|
14
|
+
def __init__(self,endpoint,authorization=None,*,session=None):
|
|
15
|
+
try:target=urlsplit(endpoint)
|
|
16
|
+
except(ValueError,TypeError):raise ValueError('Use the exact private parser endpoint')from None
|
|
17
|
+
if(not isinstance(endpoint,str)or len(endpoint)>2000 or target.scheme!='https'or not target.hostname or target.path!='/extract'
|
|
18
|
+
or target.query or target.fragment or target.username or target.password or any(ord(c)<33 or ord(c)>126 for c in endpoint)):raise ValueError('Use the owned private HTTPS /extract endpoint')
|
|
19
|
+
try:port=target.port
|
|
20
|
+
except ValueError:raise ValueError('Use the owned private parser port')from None
|
|
21
|
+
if port is not None and not 1<=port<=65535:raise ValueError('Use the owned private parser port')
|
|
22
|
+
if authorization is not None and not callable(authorization):raise ValueError('Use owned native caller authorization')
|
|
23
|
+
self.endpoint=endpoint;self.authorization=authorization;self.session=session or requests.Session();self.session.trust_env=False
|
|
24
|
+
def __call__(self,raw):
|
|
25
|
+
digest=digest_pdf(raw);headers={'Content-Type':'application/pdf'}
|
|
26
|
+
try:
|
|
27
|
+
if self.authorization is not None:
|
|
28
|
+
token=self.authorization()
|
|
29
|
+
if not isinstance(token,str)or not token.startswith('Bearer ')or not 8<=len(token)<=20000 or any(ord(c)<33 or ord(c)>126 for c in token[7:]):raise ValueError('Invalid parser caller identity')
|
|
30
|
+
headers['Authorization']=token
|
|
31
|
+
deadline=time.monotonic()+125
|
|
32
|
+
with self.session.post(self.endpoint,data=raw,headers=headers,timeout=(2,115),allow_redirects=False,stream=True)as response:
|
|
33
|
+
if response.status_code in {408,429,500,502,503,504}:raise TemporaryWork('PDF parsing is temporarily unavailable')
|
|
34
|
+
if response.status_code==422:raise DocumentError('unreadable_pdf')
|
|
35
|
+
if response.status_code!=200:raise TemporaryWork('Private parser admission is unavailable')
|
|
36
|
+
content=bytearray()
|
|
37
|
+
for chunk in response.iter_content(1):
|
|
38
|
+
content.extend(chunk)
|
|
39
|
+
if len(content)>120500 or time.monotonic()>deadline:raise ValueError('Parser response exceeds its boundary')
|
|
40
|
+
value=json.loads(content,object_pairs_hook=_object,parse_constant=lambda _:(_ for _ in ()).throw(ValueError('Nonfinite parser output')))
|
|
41
|
+
if not isinstance(value,dict)or set(value)!={'status','document'}or value['status']!='ok':raise ValueError('Invalid parser response')
|
|
42
|
+
document=value['document'];document_evidence(document)
|
|
43
|
+
if document['sha256']!=digest:raise ValueError('Parser original digest differs')
|
|
44
|
+
return document
|
|
45
|
+
except(DocumentError,TemporaryWork):raise
|
|
46
|
+
except Exception:raise TemporaryWork('Private parser could not confirm extraction')from None
|
|
47
|
+
|
|
48
|
+
def google_parser_authorization(audience,session=None):
|
|
49
|
+
if not isinstance(audience,str)or not re.fullmatch(r'https://[a-z0-9-]+(?:\.[a-z0-9-]+)?\.run\.app',audience):raise ValueError('Use the owned Cloud Run parser audience')
|
|
50
|
+
session=session or requests.Session();session.trust_env=False
|
|
51
|
+
def read():
|
|
52
|
+
deadline=time.monotonic()+4
|
|
53
|
+
with session.get('http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity',params={'audience':audience,'format':'full'},headers={'Metadata-Flavor':'Google'},allow_redirects=False,timeout=(1,2),stream=True)as response:
|
|
54
|
+
if response.status_code!=200 or response.headers.get('Metadata-Flavor')!='Google':raise TemporaryWork('Parser workload identity unavailable')
|
|
55
|
+
raw=bytearray()
|
|
56
|
+
for chunk in response.iter_content(1):
|
|
57
|
+
raw.extend(chunk)
|
|
58
|
+
if len(raw)>16384 or time.monotonic()>deadline:raise TemporaryWork('Parser workload identity unavailable')
|
|
59
|
+
value=raw.decode('ascii')
|
|
60
|
+
if not value or any(ord(c)<33 or ord(c)>126 for c in value):raise TemporaryWork('Parser workload identity unavailable')
|
|
61
|
+
return'Bearer '+value
|
|
62
|
+
return read
|
|
63
|
+
|
|
64
|
+
def azure_parser_authorization(audience,worker_client,credential=None):
|
|
65
|
+
uuid=r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
|
|
66
|
+
if any(not isinstance(value,str)or not re.fullmatch(uuid,value)for value in [audience,worker_client]):raise ValueError('Use the exact owned parser audience and worker client')
|
|
67
|
+
if credential is None:
|
|
68
|
+
from azure.identity import ManagedIdentityCredential
|
|
69
|
+
credential=ManagedIdentityCredential(client_id=worker_client,retry_total=0,connection_timeout=1,read_timeout=2)
|
|
70
|
+
def read():
|
|
71
|
+
try:return'Bearer '+credential.get_token('api://'+audience+'/.default').token
|
|
72
|
+
except Exception:raise TemporaryWork('Parser workload identity unavailable')from None
|
|
73
|
+
return read
|
|
74
|
+
|
|
75
|
+
def ibm_parser_authorization(path):
|
|
76
|
+
from pathlib import Path
|
|
77
|
+
import os
|
|
78
|
+
import stat
|
|
79
|
+
source=Path(path)
|
|
80
|
+
if not source.is_absolute():raise ValueError('Use the separately mounted owned parser token file')
|
|
81
|
+
def read():
|
|
82
|
+
try:
|
|
83
|
+
metadata=source.stat()
|
|
84
|
+
if not stat.S_ISREG(metadata.st_mode)or metadata.st_uid!=os.geteuid()or metadata.st_mode&0o077 or metadata.st_size!=64:raise ValueError('Unowned or invalid parser token file')
|
|
85
|
+
with source.open('rb')as stream:token=stream.read(65).decode('ascii')
|
|
86
|
+
if not re.fullmatch(r'[0-9a-f]{64}',token):raise ValueError('Invalid parser token')
|
|
87
|
+
return'Bearer '+token
|
|
88
|
+
except Exception:raise TemporaryWork('Parser admission credential unavailable')from None
|
|
89
|
+
return read
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""The actual storage -> isolated parser -> model -> independent decoder composition."""
|
|
2
|
+
from invoice_document import DocumentError
|
|
3
|
+
from invoice_extraction import extract_invoice,document_evidence
|
|
4
|
+
from invoice_object_store import ObjectUnavailable,digest_pdf
|
|
5
|
+
from workflow_errors import TemporaryWork,PermanentWork
|
|
6
|
+
from invoice_retention import retained
|
|
7
|
+
|
|
8
|
+
class InvoiceProcessor:
|
|
9
|
+
def __init__(self,objects,parser,model):
|
|
10
|
+
if not callable(parser)or not callable(getattr(model,'generate',None)):raise ValueError('Use the owned parser and model adapters')
|
|
11
|
+
self.objects=objects;self.parser=parser;self.model=model
|
|
12
|
+
def __call__(self,row):
|
|
13
|
+
if not retained(row):raise PermanentWork('Invoice retention period ended; do not read the original or call the model')
|
|
14
|
+
try:
|
|
15
|
+
source=row['source_ref'];raw=self.objects.load(str(row['account_id']),source)
|
|
16
|
+
if digest_pdf(raw)!=source['sha256']:raise ValueError('Original identity changed')
|
|
17
|
+
document=self.parser(raw);document_evidence(document)
|
|
18
|
+
if document['sha256']!=source['sha256']:raise ValueError('Parsed original identity changed')
|
|
19
|
+
except DocumentError:raise PermanentWork('This PDF needs review before extraction can continue')from None
|
|
20
|
+
except(ObjectUnavailable,TemporaryWork):raise TemporaryWork('Original or parser temporarily unavailable')from None
|
|
21
|
+
except Exception:raise PermanentWork('Original or parsed evidence could not be verified')from None
|
|
22
|
+
try:return extract_invoice(document,self.model.generate)
|
|
23
|
+
except(ValueError,TypeError,UnicodeError,RecursionError):raise PermanentWork('Invoice suggestions need review')from None
|
|
24
|
+
except Exception:raise TemporaryWork('Model processing is temporarily unavailable')from None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Invoice payload access expires independently of asynchronous physical cleanup."""
|
|
2
|
+
from datetime import datetime,timedelta,timezone
|
|
3
|
+
|
|
4
|
+
def retained(row):
|
|
5
|
+
created=row.get('created_at')
|
|
6
|
+
if isinstance(created,str):
|
|
7
|
+
try:created=datetime.fromisoformat(created)
|
|
8
|
+
except ValueError:return False
|
|
9
|
+
if not isinstance(created,datetime)or created.tzinfo is None:return False
|
|
10
|
+
now=datetime.now(timezone.utc)
|
|
11
|
+
return now-timedelta(days=90)<created<=now+timedelta(minutes=5)
|
|
12
|
+
|
|
13
|
+
def current(row):
|
|
14
|
+
from durable_workflow import Missing
|
|
15
|
+
if not retained(row):raise Missing('Invoice retention period ended')
|
|
16
|
+
return row
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Turn native platform secret injections into private runtime files, never exports.
|
|
2
|
+
|
|
3
|
+
The infrastructure supplies secret references, not values in Terraform/source.
|
|
4
|
+
Platforms resolve them at startup. Rotation requires the documented workload
|
|
5
|
+
rollout; this module does not claim cloud-mounted files refresh automatically.
|
|
6
|
+
The untrusted parser never receives these values or this directory.
|
|
7
|
+
"""
|
|
8
|
+
import atexit
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
import shutil
|
|
13
|
+
import tempfile
|
|
14
|
+
|
|
15
|
+
def prepare_runtime_environment(provider,environment,role):
|
|
16
|
+
if provider not in {'aws','azure','gcp','ibm'}or role not in {'api','worker'}:raise ValueError('Use the owned native workload and role')
|
|
17
|
+
env=dict(environment)
|
|
18
|
+
if any(name in env for name in ['PARSER_SHARED_TOKEN','PARSER_SHARED_TOKEN_FILE'])and(provider!='ibm'or role!='worker'):raise ValueError('Only the IBM extraction worker receives parser admission authority')
|
|
19
|
+
if 'PARSER_SHARED_TOKEN'in env and(not isinstance(env['PARSER_SHARED_TOKEN'],str)or not re.fullmatch(r'[0-9a-f]{64}',env['PARSER_SHARED_TOKEN'])):raise ValueError('Use a separately provisioned 256-bit parser token')
|
|
20
|
+
if role=='api'and any(name in env for name in ['DESTINATION_TOKEN','DESTINATION_TOKEN_FILE']):raise ValueError('Do not inject outbound credentials into the API')
|
|
21
|
+
if provider!='ibm'and'DATABASE_PASSWORD'in env:raise ValueError('IAM database workloads must not receive a SQL password')
|
|
22
|
+
mapping={'PARSER_SHARED_TOKEN':('PARSER_SHARED_TOKEN_FILE','parser-token',64),'DATABASE_CA_PEM':('DATABASE_CA_FILE','database-ca.pem',256000),'DATABASE_PASSWORD':('DATABASE_PASSWORD_FILE','database-password',500),'DESTINATION_TOKEN':('DESTINATION_TOKEN_FILE','destination-token',16000)}
|
|
23
|
+
selected=[]
|
|
24
|
+
for name,(pointer,filename,maximum)in mapping.items():
|
|
25
|
+
if name not in env:continue
|
|
26
|
+
value=env[name]
|
|
27
|
+
if pointer in env or not isinstance(value,str)or not value or len(value.encode('utf-8'))>maximum or'\0'in value:raise ValueError('Invalid or conflicting native secret injection')
|
|
28
|
+
if name=='DESTINATION_TOKEN'and any(ord(c)<33 or ord(c)>126 for c in value):raise ValueError('Use the owned opaque action token')
|
|
29
|
+
if name=='DATABASE_CA_PEM'and'-----BEGIN CERTIFICATE-----'not in value:raise ValueError('Use the native database CA certificate')
|
|
30
|
+
selected.append((name,pointer,filename,value))
|
|
31
|
+
if not selected:return env
|
|
32
|
+
directory=Path(tempfile.mkdtemp(prefix='atmem-private-runtime-'));directory.chmod(0o700)
|
|
33
|
+
try:
|
|
34
|
+
for name,pointer,filename,value in selected:
|
|
35
|
+
path=directory/filename
|
|
36
|
+
# Private at creation, even under a permissive inherited umask.
|
|
37
|
+
descriptor=os.open(path,os.O_WRONLY|os.O_CREAT|os.O_EXCL,0o600)
|
|
38
|
+
with os.fdopen(descriptor,'wb')as stream:stream.write(value.encode('utf-8'))
|
|
39
|
+
env[pointer]=str(path);env.pop(name)
|
|
40
|
+
if environment is os.environ:os.environ.pop(name,None)
|
|
41
|
+
atexit.register(shutil.rmtree,directory,ignore_errors=True)
|
|
42
|
+
return env
|
|
43
|
+
except BaseException:shutil.rmtree(directory,ignore_errors=True);raise
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Trusted bounded worker child. JSON-only protocol, no request-selected commands."""
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import sys
|
|
6
|
+
sys.path.insert(0,str(Path(__file__).resolve().parent))
|
|
7
|
+
from invoice_native import native_objects,owned_deployment,destination_contract,mounted_secret
|
|
8
|
+
from invoice_processing import InvoiceProcessor
|
|
9
|
+
from invoice_parser_transport import ParserClient,google_parser_authorization,azure_parser_authorization,ibm_parser_authorization
|
|
10
|
+
from approved_http_destination import ApprovedHttpDestination
|
|
11
|
+
from workflow_contract import normalized_contract
|
|
12
|
+
from workflow_errors import TemporaryWork,PermanentWork,ExternalOutcomeUnknown,DestinationNotAttempted,InvalidDispatch
|
|
13
|
+
from structured_output import _object
|
|
14
|
+
from policy_review import verify_policy_review
|
|
15
|
+
|
|
16
|
+
def replay_review(environment,contract):
|
|
17
|
+
encoded=environment.get('DESTINATION_REPLAY_REVIEW_BASE64','')
|
|
18
|
+
if not encoded:return False
|
|
19
|
+
if not isinstance(encoded,str)or len(encoded)>8192:raise ValueError('Invalid owned destination review')
|
|
20
|
+
verify_policy_review(encoded,{'contract':contract,'idempotency':'same-key-same-payload-one-effect'})
|
|
21
|
+
return True
|
|
22
|
+
|
|
23
|
+
def native_processor(provider,environment,*,objects=None,parser=None,model=None):
|
|
24
|
+
if provider not in {'aws','azure','gcp','ibm'}:raise ValueError('Unsupported owned model provider')
|
|
25
|
+
env=environment
|
|
26
|
+
if model is None:
|
|
27
|
+
if provider=='aws':
|
|
28
|
+
from aws_json_model import BedrockJsonModel,read_model_config
|
|
29
|
+
model=BedrockJsonModel(read_model_config(env))
|
|
30
|
+
elif provider=='azure':
|
|
31
|
+
from azure_structured import AzureModel,read_model_config
|
|
32
|
+
model=AzureModel(read_model_config(env))
|
|
33
|
+
elif provider=='gcp':
|
|
34
|
+
from gcp_structured import VertexModel,read_model_config
|
|
35
|
+
model=VertexModel(read_model_config(env))
|
|
36
|
+
elif provider=='ibm':
|
|
37
|
+
from ibm_structured import WatsonModel,read_model_config
|
|
38
|
+
# Internal workspace UUID and IBM cloud account are different owners.
|
|
39
|
+
model=WatsonModel(read_model_config({**env,'ACCOUNT_ID':env['IBM_ACCOUNT_ID']}))
|
|
40
|
+
else:raise ValueError('Unsupported owned model provider')
|
|
41
|
+
if parser is None:
|
|
42
|
+
authorization=google_parser_authorization(env['PARSER_AUDIENCE'])if provider=='gcp'else azure_parser_authorization(env['PARSER_AUDIENCE'],env['WORKLOAD_IDENTITY_CLIENT_ID'])if provider=='azure'else ibm_parser_authorization(env['PARSER_SHARED_TOKEN_FILE'])if provider=='ibm'else None
|
|
43
|
+
# AWS uses owned network restrictions; IBM additionally requires a
|
|
44
|
+
# separately provisioned parser-only token. No public anonymous parser URL
|
|
45
|
+
# is supplied by a browser/model. Infrastructure must prove that wiring.
|
|
46
|
+
parser=ParserClient(env['PARSER_ENDPOINT'],authorization)
|
|
47
|
+
return InvoiceProcessor(objects if objects is not None else native_objects(provider,env),parser,model)
|
|
48
|
+
|
|
49
|
+
def dispatch_operation(operation,identity,environment):
|
|
50
|
+
from invoice_retention import retained
|
|
51
|
+
if not retained(operation):raise InvalidDispatch('Invoice retention period ended; no request was made')
|
|
52
|
+
env=environment;contract=destination_contract(env)
|
|
53
|
+
if normalized_contract(env['DESTINATION_ENDPOINT'],env['DESTINATION_SCOPE'])!=contract:raise InvalidDispatch('Destination differs from the approved contract')
|
|
54
|
+
try:verified=replay_review(env,contract)
|
|
55
|
+
except Exception:raise DestinationNotAttempted('Destination review must be renewed; no request was made')from None
|
|
56
|
+
destination=ApprovedHttpDestination(env['DESTINATION_ENDPOINT'],mounted_secret(env['DESTINATION_TOKEN_FILE'],maximum=20000),destination_scope=env['DESTINATION_SCOPE'],idempotency_verified=verified)
|
|
57
|
+
return destination(operation,**identity)
|
|
58
|
+
|
|
59
|
+
def main():
|
|
60
|
+
mode=sys.argv[1]if len(sys.argv)==2 else None;status='temporary'if mode=='extract'else'unknown';result={}
|
|
61
|
+
try:
|
|
62
|
+
raw=sys.stdin.buffer.read(140001)
|
|
63
|
+
if len(raw)>140000:raise ValueError('Stage input exceeds its boundary')
|
|
64
|
+
value=json.loads(raw,object_pairs_hook=_object)
|
|
65
|
+
if not isinstance(value,dict)or set(value)!={'operation','identity'}or not isinstance(value['operation'],dict)or not isinstance(value['identity'],dict):raise ValueError('Invalid owned stage input')
|
|
66
|
+
provider=owned_deployment()['provider']
|
|
67
|
+
if mode=='extract':
|
|
68
|
+
if value['identity']:raise ValueError('Extraction cannot select an action identity')
|
|
69
|
+
result=native_processor(provider,os.environ)(value['operation']);status='ok'
|
|
70
|
+
elif mode=='dispatch':result=dispatch_operation(value['operation'],value['identity'],os.environ);status='ok'
|
|
71
|
+
else:raise ValueError('Use the owned extraction or dispatch command')
|
|
72
|
+
except PermanentWork:status='permanent'if mode=='extract'else'invalid'
|
|
73
|
+
except InvalidDispatch:status='invalid'
|
|
74
|
+
except DestinationNotAttempted:status='not_attempted'
|
|
75
|
+
except TemporaryWork:status='temporary'
|
|
76
|
+
except ExternalOutcomeUnknown:status='unknown'
|
|
77
|
+
except Exception:pass
|
|
78
|
+
sys.stdout.write(json.dumps({'status':status,'result':result},ensure_ascii=False,allow_nan=False))
|
|
79
|
+
|
|
80
|
+
if __name__=='__main__':main()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Fixed browser assets and reviewed public sign-in configuration, no private data."""
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import re
|
|
4
|
+
from urllib.parse import urlsplit
|
|
5
|
+
from fastapi.responses import FileResponse
|
|
6
|
+
|
|
7
|
+
def install_web(app,configuration,root=None):
|
|
8
|
+
if not isinstance(configuration,dict):raise ValueError('Supply owned public browser configuration')
|
|
9
|
+
config=dict(configuration);mode=config.get('mode')
|
|
10
|
+
if mode=='proxy':
|
|
11
|
+
if set(config)!={'mode','loginPath','logoutPath'}:raise ValueError('Invalid proxy sign-in configuration')
|
|
12
|
+
for field in ['loginPath','logoutPath']:
|
|
13
|
+
value=config[field]
|
|
14
|
+
if field=='logoutPath'and value is None:continue
|
|
15
|
+
if not isinstance(value,str)or not value.startswith('/')or value.startswith('//')or '\\'in value or any(ord(c)<33 or ord(c)>126 for c in value):raise ValueError('Use an owned same-origin sign-in path')
|
|
16
|
+
connect="'self'"
|
|
17
|
+
elif mode=='oauth-pkce':
|
|
18
|
+
if set(config)!={'mode','authOrigin','authorizationEndpoint','tokenEndpoint','clientId','scopes'}:raise ValueError('Invalid public PKCE configuration')
|
|
19
|
+
origin=urlsplit(config['authOrigin'])
|
|
20
|
+
if origin.scheme!='https'or not re.fullmatch(r'[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?(?::443)?',origin.netloc)or'..'in origin.netloc or origin.path not in {'','/'}or origin.username or origin.query or origin.fragment:raise ValueError('Use the exact trusted HTTPS authorization origin')
|
|
21
|
+
for field in ['authorizationEndpoint','tokenEndpoint']:
|
|
22
|
+
value=urlsplit(config[field])
|
|
23
|
+
if value.scheme!='https'or value.netloc!=origin.netloc or value.username or value.query or value.fragment:raise ValueError('Sign-in endpoints must belong to the trusted authority')
|
|
24
|
+
for field in ['clientId','scopes']:
|
|
25
|
+
if not isinstance(config[field],str)or not 1<=len(config[field])<=1024 or any(ord(c)<32 or ord(c)>126 for c in config[field]):raise ValueError('Invalid public client configuration')
|
|
26
|
+
connect="'self' "+origin.scheme+'://'+origin.netloc
|
|
27
|
+
else:raise ValueError('Use native proxy or authorization-code PKCE sign-in')
|
|
28
|
+
assets=Path(root or Path(__file__).parent)
|
|
29
|
+
for name in ['invoice-web.html','invoice-web.js','invoice-web.css']:
|
|
30
|
+
if not(assets/name).is_file():raise ValueError('Invoice browser asset is missing')
|
|
31
|
+
@app.get('/config.json')
|
|
32
|
+
def public_configuration():return config
|
|
33
|
+
@app.get('/')
|
|
34
|
+
def index():return FileResponse(assets/'invoice-web.html',media_type='text/html')
|
|
35
|
+
@app.get('/app.js')
|
|
36
|
+
def script():return FileResponse(assets/'invoice-web.js',media_type='text/javascript')
|
|
37
|
+
@app.get('/app.css')
|
|
38
|
+
def style():return FileResponse(assets/'invoice-web.css',media_type='text/css')
|
|
39
|
+
return "default-src 'self'; script-src 'self'; style-src 'self'; connect-src "+connect+"; frame-ancestors 'none'; base-uri 'none'; form-action 'self'"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Dedicated native queue worker; private process liveness, never a business API."""
|
|
2
|
+
import asyncio
|
|
3
|
+
from http.server import BaseHTTPRequestHandler,ThreadingHTTPServer
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import sys
|
|
7
|
+
import threading
|
|
8
|
+
sys.path.insert(0,str(Path(__file__).resolve().parent))
|
|
9
|
+
from invoice_native import native_database,owned_deployment,destination_contract
|
|
10
|
+
from invoice_stage import replay_review
|
|
11
|
+
from workflow_process_stage import ProcessStage
|
|
12
|
+
from workflow_worker import WorkflowRuntime
|
|
13
|
+
from workflow_contract import normalized_contract
|
|
14
|
+
from invoice_runtime_secrets import prepare_runtime_environment
|
|
15
|
+
|
|
16
|
+
COMMON=['DOCUMENT_BUCKET','REGION','PARSER_ENDPOINT','MAX_OUTPUT_TOKENS']
|
|
17
|
+
EXTRACT_KEYS={
|
|
18
|
+
'aws':COMMON+['AWS_ACCOUNT_ID','MODEL_ID','AWS_CONTAINER_CREDENTIALS_RELATIVE_URI','AWS_CONTAINER_CREDENTIALS_FULL_URI','AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE','AWS_REGION','AWS_DEFAULT_REGION'],
|
|
19
|
+
'azure':COMMON+['PARSER_AUDIENCE','DOCUMENT_ACCOUNT','WORKLOAD_IDENTITY_CLIENT_ID','MANAGED_IDENTITY_CLIENT_ID','MODEL_RESOURCE_ID','MODEL_ENDPOINT','MODEL_DEPLOYMENT','IDENTITY_ENDPOINT','IDENTITY_HEADER','MSI_ENDPOINT','MSI_SECRET'],
|
|
20
|
+
'gcp':COMMON+['PROJECT_ID','MODEL_ID','POLICY_REVIEW_BASE64','PARSER_AUDIENCE'],
|
|
21
|
+
'ibm':COMMON+['PARSER_SHARED_TOKEN_FILE','IBM_ACCOUNT_ID','WATSONX_PROJECT_ID','RUNTIME_INSTANCE_ID','MODEL_REGION','MODEL_ID','IAM_PROFILE_ID','POLICY_REVIEW_BASE64']}
|
|
22
|
+
|
|
23
|
+
def stage_environment(environment,names):
|
|
24
|
+
return{'PATH':'/usr/local/bin:/usr/bin:/bin','LANG':'C.UTF-8','PYTHONDONTWRITEBYTECODE':'1',**{name:environment[name]for name in names if name in environment}}
|
|
25
|
+
|
|
26
|
+
def create_native_worker(provider,environment,*,connection=None):
|
|
27
|
+
if provider not in EXTRACT_KEYS:raise ValueError('Unsupported owned invoice provider')
|
|
28
|
+
env=prepare_runtime_environment(provider,environment,'worker');contract=destination_contract(env);verified=replay_review(env,contract);stage=Path(__file__).parent/'invoice_stage.py'
|
|
29
|
+
if normalized_contract(env['DESTINATION_ENDPOINT'],env['DESTINATION_SCOPE'])!=contract:raise ValueError('Worker destination differs from the approved integration identity')
|
|
30
|
+
extract=ProcessStage([sys.executable,'-I',str(stage),'extract'],kind='extract',timeout_seconds=180,environment=stage_environment(env,EXTRACT_KEYS[provider]))
|
|
31
|
+
dispatch=ProcessStage([sys.executable,'-I',str(stage),'dispatch'],kind='dispatch',timeout_seconds=45,idempotency_verified=verified,environment=stage_environment(env,['DESTINATION_ENDPOINT','DESTINATION_SCOPE','DESTINATION_TOKEN_FILE','DESTINATION_CONTRACT_BASE64','DESTINATION_REPLAY_REVIEW_BASE64']))
|
|
32
|
+
return WorkflowRuntime(connection if connection is not None else native_database(provider,env,'worker'),extract,dispatch,destination_contract=contract,idempotent_destination=verified,namespace=env['WORKFLOW_NAMESPACE'],lease_seconds=600)
|
|
33
|
+
|
|
34
|
+
class Liveness(BaseHTTPRequestHandler):
|
|
35
|
+
def log_message(self,*args):pass
|
|
36
|
+
def do_GET(self):
|
|
37
|
+
self.send_response(200 if self.path=='/healthz'else 404);self.send_header('Content-Length','0');self.end_headers()
|
|
38
|
+
|
|
39
|
+
def main():
|
|
40
|
+
runtime=create_native_worker(owned_deployment()['provider'],os.environ);port=int(os.environ.get('PORT','8080'))
|
|
41
|
+
if not 1024<=port<=65535:raise ValueError('Use the owned nonprivileged liveness port')
|
|
42
|
+
# Process liveness only. SQL bootstrap/restore and destination acceptance are
|
|
43
|
+
# separate deployment checks; this endpoint claims no business readiness.
|
|
44
|
+
server=ThreadingHTTPServer(('0.0.0.0',port),Liveness);threading.Thread(target=server.serve_forever,daemon=True).start()
|
|
45
|
+
# Default pairs one worker execution with one parser slot. Scale both sides
|
|
46
|
+
# together only after throughput/quotas and backpressure are qualified.
|
|
47
|
+
try:asyncio.run(runtime.run(concurrency=1))
|
|
48
|
+
finally:server.shutdown();server.server_close()
|
|
49
|
+
|
|
50
|
+
if __name__=='__main__':main()
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
cffi==2.1.1 --hash=sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2
|
|
2
|
+
cryptography==50.0.2 --hash=sha256:9dab55f57c74c3cad24c323bacbbd04be4705ba6eb0d92e920b1fc4837ed5079
|
|
3
|
+
pycparser==3.12 --hash=sha256:a076f3f489b39b43ed13563a1dafe42447445bec2e294154ec5c57fcdda4c85e
|
|
4
|
+
PyJWT==2.15.1 --hash=sha256:42d59d631f7768a1028a64c7ff581a9bf7519804daf91fc5b6c56e30eec5e193
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Scoped operator-attested policy review. Never fabricates a provider approval API."""
|
|
2
|
+
import base64
|
|
3
|
+
from datetime import datetime,timezone
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
from structured_output import _object
|
|
7
|
+
from structured_http import PolicyUnverified
|
|
8
|
+
|
|
9
|
+
def verify_policy_review(encoded,expected,now=None):
|
|
10
|
+
try:
|
|
11
|
+
review=json.loads(base64.b64decode(encoded,validate=True),object_pairs_hook=_object)
|
|
12
|
+
if any(review.get(key)!=value for key,value in expected.items()):raise PolicyUnverified()
|
|
13
|
+
if not isinstance(review.get('approvedBy'),str) or not review['approvedBy'].strip():raise PolicyUnverified()
|
|
14
|
+
if not re.fullmatch(r'[0-9a-f]{64}',review.get('evidenceSha256','')) or review['evidenceSha256']=='0'*64:raise PolicyUnverified()
|
|
15
|
+
expiry=datetime.fromisoformat(review['expiresAt']);now=now or datetime.now(timezone.utc)
|
|
16
|
+
if expiry.tzinfo is None or not 0<(expiry-now).total_seconds()<=31*86400:raise PolicyUnverified()
|
|
17
|
+
return review
|
|
18
|
+
except Exception:raise PolicyUnverified() from None
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"image": "postgres:17-alpine",
|
|
3
|
+
"manifests": {
|
|
4
|
+
"linux/amd64": "sha256:4717f90960a225c2d1c5dac50508c401230f693ff626e06e84e6db0a68ded508",
|
|
5
|
+
"linux/arm64": "sha256:1108a8fe22dff4eab48870e081be046d549ddc1b6f5972e0a766eaf1e0b1003c"
|
|
6
|
+
},
|
|
7
|
+
"reviewedAt": "2026-11-10",
|
|
8
|
+
"boundary": "Official Docker PostgreSQL 17 image manifests for local qualification only; not proof of managed cloud PostgreSQL availability, privileges, patch level or deployment.",
|
|
9
|
+
"variants": {
|
|
10
|
+
"18": {
|
|
11
|
+
"image": "postgres:18-alpine",
|
|
12
|
+
"manifests": {
|
|
13
|
+
"linux/amd64": "sha256:300ebd02c6d4de9ee27ad7f6855d5d21b4d3a4a5117767c1197d284c635d9736",
|
|
14
|
+
"linux/arm64": "sha256:c935aff069a7bbe5c286411a08e9678850d79be7848b190a0e4637b266478626"
|
|
15
|
+
},
|
|
16
|
+
"reviewedAt": "2026-11-10",
|
|
17
|
+
"manifestSha256": "123b17998ccaf47e53b502e8c6a1e79afd8f579c6f3eec83c563da026f957395",
|
|
18
|
+
"source": "https://registry-1.docker.io/v2/library/postgres/manifests/18-alpine"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|