@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
package/src/review.mjs
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// Architecture review: deterministic, provider-neutral rules over the project model.
|
|
2
|
+
// See specs/003-architecture-review. Each finding names its rule, so it can be traced.
|
|
3
|
+
|
|
4
|
+
export const RULES_VERSION = "1.0.0";
|
|
5
|
+
export const ATTRIBUTES = [
|
|
6
|
+
["security", "Security & controls"],
|
|
7
|
+
["reliability", "Reliability"],
|
|
8
|
+
["availability", "Availability"],
|
|
9
|
+
["scalability", "Scalability"],
|
|
10
|
+
["performance", "Performance"],
|
|
11
|
+
["maintainability", "Maintainability"],
|
|
12
|
+
["cost", "Cost"],
|
|
13
|
+
];
|
|
14
|
+
export const SEVERITIES = ["blocker", "major", "minor", "info"];
|
|
15
|
+
|
|
16
|
+
// What a block does, whether runnable (kind) or sketched (role).
|
|
17
|
+
export function roleOf(n) {
|
|
18
|
+
const { kind, role } = n.data;
|
|
19
|
+
if (role) return role;
|
|
20
|
+
return (
|
|
21
|
+
{ source: "data", stream: "data", history: "data", features: "ingest", train: "model", registry: "model", predict: "model", monitor: "monitor", agent: "llm", guard: "guard", tool: "app", output: "output" }[kind] || "other"
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
const isHuman = (n) => roleOf(n) === "human" || /\b(approv|human|review queue|person)\b/i.test(n.data.label);
|
|
25
|
+
const isGuard = (n) => roleOf(n) === "guard" || isHuman(n);
|
|
26
|
+
|
|
27
|
+
function downstream(p, id, seen = new Set()) {
|
|
28
|
+
for (const e of p.edges)
|
|
29
|
+
if (e.source === id && !seen.has(e.target)) {
|
|
30
|
+
seen.add(e.target);
|
|
31
|
+
downstream(p, e.target, seen);
|
|
32
|
+
}
|
|
33
|
+
return seen;
|
|
34
|
+
}
|
|
35
|
+
// Paths from `from` to any node matching `to` that avoid nodes matching `via`.
|
|
36
|
+
function reachesAvoiding(p, from, to, via) {
|
|
37
|
+
const stack = [from],
|
|
38
|
+
seen = new Set([from]);
|
|
39
|
+
while (stack.length) {
|
|
40
|
+
const id = stack.pop();
|
|
41
|
+
for (const e of p.edges.filter((x) => x.source === id)) {
|
|
42
|
+
const n = p.nodes.find((x) => x.id === e.target);
|
|
43
|
+
if (!n || seen.has(n.id) || via(n)) continue;
|
|
44
|
+
if (to(n)) return true;
|
|
45
|
+
seen.add(n.id);
|
|
46
|
+
stack.push(n.id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const hasNeed = (p, category, re) =>
|
|
53
|
+
(p.needs || []).some((r) => r.category === category && (!re || re.test(`${r.statement} ${r.measure?.metric || ""}`)));
|
|
54
|
+
const fact = (p, name) => [...(p.facts || [])].reverse().find((f) => f.name === name);
|
|
55
|
+
|
|
56
|
+
const RULES = [
|
|
57
|
+
{
|
|
58
|
+
id: "SEC-001",
|
|
59
|
+
attribute: "security",
|
|
60
|
+
severity: "blocker",
|
|
61
|
+
check(p) {
|
|
62
|
+
const llms = p.nodes.filter((n) => roleOf(n) === "llm");
|
|
63
|
+
const exits = (n) => ["app", "output"].includes(roleOf(n));
|
|
64
|
+
const open = llms.filter((n) => reachesAvoiding(p, n.id, exits, isGuard));
|
|
65
|
+
return open.map((n) => ({
|
|
66
|
+
statement: `${n.data.label} can reach users or systems without a guardrail or approval step.`,
|
|
67
|
+
rationale: "Generated content can be wrong, unsafe or leak data; it needs a check before it leaves the system.",
|
|
68
|
+
action: "Define and represent output validation or an approval control where needed; specify failure behavior and test it. Verify source authorization before retrieval and citation grounding separately: a guardrail block alone proves neither.",
|
|
69
|
+
components: [n.id],
|
|
70
|
+
}));
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "SEC-002",
|
|
75
|
+
attribute: "security",
|
|
76
|
+
severity: "major",
|
|
77
|
+
check(p) {
|
|
78
|
+
const sensitive = p.nodes.filter((n) => n.data.config?.classification === "Confidential");
|
|
79
|
+
const flagged = fact(p, "data.sensitive")?.value === true;
|
|
80
|
+
if (!sensitive.length && !flagged) return [];
|
|
81
|
+
if (hasNeed(p, "compliance", /stay|resid|region|locat/i)) return [];
|
|
82
|
+
return [
|
|
83
|
+
{
|
|
84
|
+
statement: "Sensitive data is involved but where it must be stored is not stated.",
|
|
85
|
+
rationale: "Data residency rules decide which regions and services are allowed.",
|
|
86
|
+
action: "Add a compliance requirement such as “data stays in the EU”, and set regions on data blocks.",
|
|
87
|
+
components: sensitive.map((n) => n.id),
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: "SEC-003",
|
|
94
|
+
attribute: "security",
|
|
95
|
+
severity: "major",
|
|
96
|
+
check(p) {
|
|
97
|
+
const actors = p.nodes.filter((n) => ["llm", "model"].includes(roleOf(n)));
|
|
98
|
+
// Systems that receive actions (integrations), not the interface people read.
|
|
99
|
+
const apps = p.nodes.filter((n) => roleOf(n) === "app" && (n.data.kind === "tool" || /integration/i.test(n.data.category || "")));
|
|
100
|
+
const unchecked = apps.filter((a) => actors.some((m) => downstream(p, m.id).has(a.id) && reachesAvoiding(p, m.id, (x) => x.id === a.id, isHuman)));
|
|
101
|
+
if (!unchecked.length || hasNeed(p, "security", /person|human|approv/i)) return [];
|
|
102
|
+
return [
|
|
103
|
+
{
|
|
104
|
+
statement: "Automated results reach other systems with no person approving them.",
|
|
105
|
+
rationale: "Actions taken on model output (orders, emails, records) need clear human accountability.",
|
|
106
|
+
action: "Add an approval step, or record a requirement that states which actions need approval.",
|
|
107
|
+
components: unchecked.map((n) => n.id),
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "REL-001",
|
|
114
|
+
attribute: "reliability",
|
|
115
|
+
severity: "major",
|
|
116
|
+
check(p) {
|
|
117
|
+
const models = p.nodes.filter((n) => ["llm", "model"].includes(roleOf(n)));
|
|
118
|
+
if (!models.length || p.nodes.some((n) => roleOf(n) === "monitor")) return [];
|
|
119
|
+
return [
|
|
120
|
+
{
|
|
121
|
+
statement: "No monitoring for model quality or drift.",
|
|
122
|
+
rationale: "Model answers and predictions degrade quietly; someone needs to see it happen.",
|
|
123
|
+
action: "Add a monitoring block (quality, drift, cost) and decide who is alerted.",
|
|
124
|
+
components: models.map((n) => n.id),
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: "REL-002",
|
|
131
|
+
attribute: "reliability",
|
|
132
|
+
severity: "minor",
|
|
133
|
+
check(p) {
|
|
134
|
+
const apps = p.nodes.filter((n) => roleOf(n) === "app" && n.data.origin === "existing");
|
|
135
|
+
return apps.length
|
|
136
|
+
? [
|
|
137
|
+
{
|
|
138
|
+
statement: "The design depends on existing systems; their failure behaviour is not described.",
|
|
139
|
+
rationale: "If an integration is down, requests may be lost or duplicated.",
|
|
140
|
+
action: "State what happens when each existing system is unavailable (retry, queue, fallback).",
|
|
141
|
+
components: apps.map((n) => n.id),
|
|
142
|
+
},
|
|
143
|
+
]
|
|
144
|
+
: [];
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: "AVL-001",
|
|
149
|
+
attribute: "availability",
|
|
150
|
+
severity: "minor",
|
|
151
|
+
check: (p) =>
|
|
152
|
+
p.nodes.length && !hasNeed(p, "availability")
|
|
153
|
+
? [{ statement: "No availability target.", rationale: "Without one, nobody can say whether a single region or a single endpoint is enough.", action: "Add a requirement such as “available 99.5% of the time” or “business hours only”.", components: [] }]
|
|
154
|
+
: [],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: "PRF-001",
|
|
158
|
+
attribute: "performance",
|
|
159
|
+
severity: "minor",
|
|
160
|
+
check: (p) =>
|
|
161
|
+
p.nodes.some((n) => ["llm", "model"].includes(roleOf(n))) && !hasNeed(p, "performance")
|
|
162
|
+
? [{ statement: "No response-time target.", rationale: "Model size, retrieval depth and region all trade speed against cost.", action: "Add a requirement such as “responds within 5 seconds”.", components: [] }]
|
|
163
|
+
: [],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: "SCL-001",
|
|
167
|
+
attribute: "scalability",
|
|
168
|
+
severity: "info",
|
|
169
|
+
check: (p) =>
|
|
170
|
+
p.nodes.length && !fact(p, "requests.per_month") && !fact(p, "users")
|
|
171
|
+
? [{ statement: "Expected usage is unknown, so scale can't be assessed.", rationale: "Usage drives capacity, limits and cost.", action: "Tell us in the chat roughly how many people use it and how often.", components: [] }]
|
|
172
|
+
: [],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "MNT-001",
|
|
176
|
+
attribute: "maintainability",
|
|
177
|
+
severity: "minor",
|
|
178
|
+
check: (p) => {
|
|
179
|
+
const loose = (p.needs || []).filter((r) => r.kind === "nonfunctional" && !r.measure);
|
|
180
|
+
return loose.length
|
|
181
|
+
? [{ statement: `${loose.length} quality requirement${loose.length > 1 ? "s have" : " has"} no measurable target.`, rationale: "A target makes it testable and lets the review say met or not met.", action: `Add a metric and target to: ${loose.map((r) => `“${r.statement}”`).join(", ")}.`, components: [] }]
|
|
182
|
+
: [];
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: "MNT-002",
|
|
187
|
+
attribute: "maintainability",
|
|
188
|
+
severity: "minor",
|
|
189
|
+
check: (p) => {
|
|
190
|
+
const unowned = (p.decisions || []).filter((d) => d.status === "Accepted" && !d.owner?.trim());
|
|
191
|
+
return unowned.length
|
|
192
|
+
? [{ statement: `${unowned.length} accepted decision${unowned.length > 1 ? "s have" : " has"} no owner.`, rationale: "Someone must be accountable for each choice before build.", action: "Assign an owner in Design → Decisions.", components: [] }]
|
|
193
|
+
: [];
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: "CST-001",
|
|
198
|
+
attribute: "cost",
|
|
199
|
+
severity: "info",
|
|
200
|
+
check: (p) =>
|
|
201
|
+
p.nodes.length && !fact(p, "budget.per_month") && !hasNeed(p, "cost")
|
|
202
|
+
? [{ statement: "No budget stated.", rationale: "Without one, the estimate can't flag an option as too expensive.", action: "Mention a monthly running budget, or a range, in the chat.", components: [] }]
|
|
203
|
+
: [],
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
id: "DSN-001",
|
|
207
|
+
attribute: "maintainability",
|
|
208
|
+
severity: "info",
|
|
209
|
+
check: (p) => {
|
|
210
|
+
const sketch = p.nodes.filter((n) => n.data.kind === "resource");
|
|
211
|
+
return sketch.length
|
|
212
|
+
? [{ statement: `${sketch.length} block${sketch.length > 1 ? "s are" : " is"} sketch-only and can't be test-run yet.`, rationale: "Sketch blocks describe intent; runnable fixtures exist only for some workflows.", action: "Keep designing; assign a runnable behaviour in block detail when one exists.", components: sketch.map((n) => n.id) }]
|
|
213
|
+
: [];
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
const keyOf = (rule, components) => `${rule}:${[...components].sort().join(",")}`;
|
|
219
|
+
|
|
220
|
+
// Findings are recomputed from current data; accepted risks persist by rule + components.
|
|
221
|
+
export function review(full) {
|
|
222
|
+
const notes = new Set(full.nodes.filter((n) => n.data.kind === "note").map((n) => n.id));
|
|
223
|
+
const project = { ...full, nodes: full.nodes.filter((n) => !notes.has(n.id)), edges: full.edges.filter((e) => !notes.has(e.source) && !notes.has(e.target)) };
|
|
224
|
+
const accepted = project.reviewAccepted || {};
|
|
225
|
+
return RULES.flatMap((rule) =>
|
|
226
|
+
rule.check(project).map((f, i) => {
|
|
227
|
+
const key = keyOf(rule.id, f.components);
|
|
228
|
+
return {
|
|
229
|
+
id: `${rule.id}-${i + 1}`,
|
|
230
|
+
key,
|
|
231
|
+
rule: rule.id,
|
|
232
|
+
version: RULES_VERSION,
|
|
233
|
+
attribute: rule.attribute,
|
|
234
|
+
severity: rule.severity,
|
|
235
|
+
...f,
|
|
236
|
+
source: `AtMem AI Architect rule ${rule.id} v${RULES_VERSION}`,
|
|
237
|
+
status: accepted[key] ? "accepted" : "open",
|
|
238
|
+
...(accepted[key] ? { acceptance: accepted[key] } : {}),
|
|
239
|
+
};
|
|
240
|
+
}),
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function acceptRisk(project, finding, reason, owner) {
|
|
245
|
+
if (!String(reason || "").trim() || !String(owner || "").trim()) throw Error("Accepting a risk needs a reason and an owner.");
|
|
246
|
+
return {
|
|
247
|
+
...project,
|
|
248
|
+
reviewAccepted: { ...(project.reviewAccepted || {}), [finding.key]: { reason, owner, date: new Date().toLocaleDateString("en-CA") } },
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export const blockers = (findings) => findings.filter((f) => f.severity === "blocker" && f.status === "open");
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/* Credentialless, single-document Tika bridge. Configuration is operator-owned.
|
|
2
|
+
* Run inside a network-isolated, resource-limited container; Tika is not a sandbox.
|
|
3
|
+
* No URL, filename, parser option or environment setting comes from a document.
|
|
4
|
+
*/
|
|
5
|
+
import java.nio.file.Files;
|
|
6
|
+
import java.nio.file.Path;
|
|
7
|
+
import java.nio.charset.StandardCharsets;
|
|
8
|
+
import java.util.Base64;
|
|
9
|
+
import java.util.Set;
|
|
10
|
+
import org.apache.tika.detect.DefaultDetector;
|
|
11
|
+
import org.apache.tika.io.TikaInputStream;
|
|
12
|
+
import org.apache.tika.metadata.Metadata;
|
|
13
|
+
import org.apache.tika.metadata.TikaCoreProperties;
|
|
14
|
+
import org.apache.tika.parser.AutoDetectParser;
|
|
15
|
+
import org.apache.tika.parser.ParseContext;
|
|
16
|
+
import org.apache.tika.parser.RecursiveParserWrapper;
|
|
17
|
+
import org.apache.tika.parser.microsoft.OfficeParserConfig;
|
|
18
|
+
import org.apache.tika.parser.ocr.TesseractOCRConfig;
|
|
19
|
+
import org.apache.tika.sax.BasicContentHandlerFactory;
|
|
20
|
+
import org.apache.tika.sax.RecursiveParserWrapperHandler;
|
|
21
|
+
|
|
22
|
+
public final class EnterpriseDocument {
|
|
23
|
+
private static final int LIMIT = 200000;
|
|
24
|
+
private static final Set<String> TYPES = Set.of(
|
|
25
|
+
"text/plain", "text/html", "application/rtf",
|
|
26
|
+
"application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint",
|
|
27
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
28
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
29
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
30
|
+
"application/vnd.oasis.opendocument.text", "application/vnd.oasis.opendocument.spreadsheet",
|
|
31
|
+
"application/vnd.oasis.opendocument.presentation");
|
|
32
|
+
|
|
33
|
+
public static void main(String[] args) {
|
|
34
|
+
try {
|
|
35
|
+
if (args.length != 1) throw new IllegalArgumentException();
|
|
36
|
+
Path input = Path.of(args[0]);
|
|
37
|
+
if (!Files.isRegularFile(input) || Files.size(input) > 10000000 || Files.size(input) == 0)
|
|
38
|
+
throw new IllegalArgumentException();
|
|
39
|
+
Metadata root = new Metadata();
|
|
40
|
+
String detected;
|
|
41
|
+
try (TikaInputStream stream = TikaInputStream.get(input)) {
|
|
42
|
+
detected = new DefaultDetector().detect(stream, root).toString();
|
|
43
|
+
}
|
|
44
|
+
if (!TYPES.contains(detected)) {
|
|
45
|
+
System.out.print("rejected\nunsupported_format\n");
|
|
46
|
+
System.exit(2);
|
|
47
|
+
}
|
|
48
|
+
AutoDetectParser parser = new AutoDetectParser();
|
|
49
|
+
ParseContext context = new ParseContext();
|
|
50
|
+
OfficeParserConfig office = new OfficeParserConfig();
|
|
51
|
+
office.setExtractMacros(false);
|
|
52
|
+
office.setIncludeDeletedContent(false);
|
|
53
|
+
office.setIncludeMoveFromContent(false);
|
|
54
|
+
office.setIncludeHeadersAndFooters(true);
|
|
55
|
+
office.setIncludeSlideNotes(true);
|
|
56
|
+
context.set(OfficeParserConfig.class, office);
|
|
57
|
+
TesseractOCRConfig ocr = new TesseractOCRConfig();
|
|
58
|
+
ocr.setLanguage("eng");
|
|
59
|
+
ocr.setTimeoutSeconds(15);
|
|
60
|
+
ocr.setEnableImagePreprocessing(false);
|
|
61
|
+
context.set(TesseractOCRConfig.class, ocr);
|
|
62
|
+
RecursiveParserWrapperHandler handler = new RecursiveParserWrapperHandler(
|
|
63
|
+
new BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, LIMIT), 64);
|
|
64
|
+
// Recursive metadata exposes caught embedded/parse exceptions and write
|
|
65
|
+
// limits, which plain CLI text output can otherwise quietly conceal.
|
|
66
|
+
try (TikaInputStream stream = TikaInputStream.get(input)) {
|
|
67
|
+
new RecursiveParserWrapper(parser).parse(stream, handler, root, context);
|
|
68
|
+
}
|
|
69
|
+
StringBuilder text = new StringBuilder();
|
|
70
|
+
for (Metadata item : handler.getMetadataList()) {
|
|
71
|
+
for (String name : item.names()) {
|
|
72
|
+
if (name.startsWith("X-TIKA:EXCEPTION") || name.startsWith("X-TIKA:WARN") ||
|
|
73
|
+
name.contains("write_limit_reached") || name.contains("embedded_resource_limit_reached"))
|
|
74
|
+
throw new IllegalArgumentException();
|
|
75
|
+
}
|
|
76
|
+
String content = item.get(TikaCoreProperties.TIKA_CONTENT);
|
|
77
|
+
if (content != null && !content.isBlank()) text.append(content.strip()).append('\n');
|
|
78
|
+
if (text.length() > LIMIT) throw new IllegalArgumentException();
|
|
79
|
+
}
|
|
80
|
+
byte[] result = text.toString().strip().getBytes(StandardCharsets.UTF_8);
|
|
81
|
+
if (result.length == 0 || result.length > LIMIT) throw new IllegalArgumentException();
|
|
82
|
+
System.out.print("ok\n" + detected + "\n" + Base64.getEncoder().encodeToString(result) + "\n");
|
|
83
|
+
} catch (Throwable failure) {
|
|
84
|
+
// Native parser messages can contain private text, filenames and URLs.
|
|
85
|
+
System.out.print("rejected\nextraction_failed\n");
|
|
86
|
+
System.exit(2);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""A concrete, explicit normalized external-action HTTP contract.
|
|
2
|
+
|
|
3
|
+
This is not an invented vendor API. Destination operators must verify this exact
|
|
4
|
+
idempotent contract or implement a reviewed native mapping. A model/visitor cannot
|
|
5
|
+
choose the endpoint, credentials, identity header, method or replay policy.
|
|
6
|
+
"""
|
|
7
|
+
import hashlib
|
|
8
|
+
import http.client
|
|
9
|
+
import json
|
|
10
|
+
import re
|
|
11
|
+
import ssl
|
|
12
|
+
from urllib.parse import urlsplit
|
|
13
|
+
from durable_workflow import canonical,identifier
|
|
14
|
+
from workflow_errors import ExternalOutcomeUnknown,DestinationNotAttempted,InvalidDispatch
|
|
15
|
+
from workflow_contract import normalized_contract,bind_payload_contract,bind_application_contract,bind_review_policy
|
|
16
|
+
|
|
17
|
+
class ApprovedHttpDestination:
|
|
18
|
+
def __init__(self,endpoint,credential,*,destination_scope,idempotency_verified=False,tls_context=None,allowed_kinds=('document',),payload_contract=None,application_contract_sha256=None,review_policy=None):
|
|
19
|
+
try:target=urlsplit(endpoint)
|
|
20
|
+
except (TypeError,ValueError):raise ValueError('Invalid operator destination')from None
|
|
21
|
+
if (not isinstance(endpoint,str)or len(endpoint)>2000 or target.scheme!='https' or not target.hostname or target.username or target.password
|
|
22
|
+
or target.query or target.fragment or any(ord(c)<33 for c in endpoint)):raise ValueError('Use a fixed reviewed HTTPS destination without embedded credentials, query or fragment')
|
|
23
|
+
try:port=target.port or 443
|
|
24
|
+
except ValueError:raise ValueError('Invalid destination port')from None
|
|
25
|
+
if not 1<=port<=65535 or not callable(credential)or type(idempotency_verified)is not bool:raise ValueError('Invalid owned destination configuration')
|
|
26
|
+
if not isinstance(allowed_kinds,(tuple,list,set,frozenset))or not allowed_kinds or not set(allowed_kinds)<={'document','draft','account_change'}:raise ValueError('Invalid owned operation allowlist')
|
|
27
|
+
context=tls_context or ssl.create_default_context()
|
|
28
|
+
if not isinstance(context,ssl.SSLContext)or context.verify_mode!=ssl.CERT_REQUIRED or not context.check_hostname:raise ValueError('TLS certificate and hostname verification are mandatory')
|
|
29
|
+
self.host=target.hostname;self.port=port;self.path=target.path or'/';self.credential=credential;self.idempotency_verified=idempotency_verified;self.context=context;self.allowed_kinds=frozenset(allowed_kinds)
|
|
30
|
+
self.contract=bind_payload_contract(normalized_contract(endpoint,destination_scope),payload_contract)
|
|
31
|
+
if application_contract_sha256 is not None:self.contract=bind_application_contract(self.contract,application_contract_sha256)
|
|
32
|
+
self.contract=bind_review_policy(self.contract,payload_contract,review_policy)
|
|
33
|
+
self.review_policy=review_policy
|
|
34
|
+
self.payload_contract=payload_contract
|
|
35
|
+
def __call__(self,row,*,idempotency_key,payload_sha256):
|
|
36
|
+
try:identifier(idempotency_key)
|
|
37
|
+
except (ValueError,TypeError):raise InvalidDispatch('Invalid approved operation identity')from None
|
|
38
|
+
if (str(row.get('id'))!=idempotency_key or row.get('state')!='dispatching' or not row.get('approved_by')or row.get('approved_hash')!=payload_sha256
|
|
39
|
+
or row.get('kind')not in self.allowed_kinds or not isinstance(payload_sha256,str)or not re.fullmatch(r'[0-9a-f]{64}',payload_sha256)):raise InvalidDispatch('A current allowed approved dispatch snapshot is required')
|
|
40
|
+
if row.get('destination_contract')!=self.contract:raise InvalidDispatch('Approved integration identity no longer matches this destination')
|
|
41
|
+
if self.payload_contract is not None:
|
|
42
|
+
try:
|
|
43
|
+
if self.contract['payloadContractSha256']!=self.payload_contract.sha256:raise ValueError()
|
|
44
|
+
self.payload_contract.validate('source',row['source_ref']);self.payload_contract.validate('result',row['result'])
|
|
45
|
+
if self.review_policy:self.review_policy.validate_result(row['source_ref'],row['result'])
|
|
46
|
+
except (KeyError,ValueError):raise InvalidDispatch('Approved application contract no longer matches this destination')from None
|
|
47
|
+
snapshot={'kind':row['kind'],'source':row['source_ref'],'destination':row['destination_contract'],'result':row['result'],'revision':row['result_revision']}
|
|
48
|
+
if hashlib.sha256(canonical(snapshot,140000)).hexdigest()!=payload_sha256:raise InvalidDispatch('Approved payload snapshot changed')
|
|
49
|
+
# Source storage references and credentials stay inside our boundary.
|
|
50
|
+
body=canonical({'operation_id':idempotency_key,'payload_sha256':payload_sha256,'kind':row['kind'],'result':row['result']},70000)
|
|
51
|
+
try:token=self.credential()
|
|
52
|
+
except Exception:raise DestinationNotAttempted('Destination credential unavailable; no request made')from None
|
|
53
|
+
if not isinstance(token,str)or not 1<=len(token)<=16000 or any(ord(c)<33 or ord(c)>126 for c in token):raise DestinationNotAttempted('Destination credential unavailable; no request made')
|
|
54
|
+
connection=http.client.HTTPSConnection(self.host,self.port,timeout=8,context=self.context)
|
|
55
|
+
try:
|
|
56
|
+
connection.request('POST',self.path,body=body,headers={'Content-Type':'application/json','Accept':'application/json','Authorization':'Bearer '+token,'Idempotency-Key':idempotency_key})
|
|
57
|
+
response=connection.getresponse();raw=response.read(8193)
|
|
58
|
+
# No redirects, inferred success, 202-as-completed, or error-body logs.
|
|
59
|
+
if response.status not in {200,201}or len(raw)>8192 or response.getheader('Content-Type','').split(';')[0].lower()!='application/json':raise ExternalOutcomeUnknown('Destination completion is unconfirmed')
|
|
60
|
+
def unique(pairs):
|
|
61
|
+
result={}
|
|
62
|
+
for key,value in pairs:
|
|
63
|
+
if key in result:raise ValueError('Duplicate receipt field')
|
|
64
|
+
result[key]=value
|
|
65
|
+
return result
|
|
66
|
+
reply=json.loads(raw,object_pairs_hook=unique)
|
|
67
|
+
if (not isinstance(reply,dict)or set(reply)!={'operation_id','payload_sha256','external_id','status'}or reply['operation_id']!=idempotency_key
|
|
68
|
+
or reply['payload_sha256']!=payload_sha256 or reply['status']!='completed' or not isinstance(reply['external_id'],str)or not re.fullmatch(r'[A-Za-z0-9_.:/-]{1,200}',reply['external_id'])):raise ExternalOutcomeUnknown('Destination completion is unconfirmed')
|
|
69
|
+
return {'externalId':reply['external_id'],'operationId':idempotency_key,'payloadSha256':payload_sha256}
|
|
70
|
+
except ExternalOutcomeUnknown:raise
|
|
71
|
+
except Exception:raise ExternalOutcomeUnknown('Destination completion is unconfirmed')from None
|
|
72
|
+
finally:connection.close()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"image": "public.ecr.aws/lambda/python:3.13@sha256:181a54632ba2cb7945ac633bdac72c13d7b0e461a32931966ae93b429a3436b9",
|
|
3
|
+
"platform": "linux/amd64",
|
|
4
|
+
"reviewedAt": "2026-11-10",
|
|
5
|
+
"source": "https://docs.aws.amazon.com/lambda/latest/dg/python-image.html",
|
|
6
|
+
"boundary": "Official AWS Python 3.13 x86_64 image manifest observed from public ECR. Local qualification only; Lambda managed-runtime patch level and account behavior require separate destination evidence."
|
|
7
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"requirements": "boto3==1.43.123 --hash=sha256:d18d66e1e13faa0c25d0b1b8c5ce946e29fb5fc0b6456b655a93a678ff4cc313\nbotocore==1.43.123 --hash=sha256:e30580f9c1282c321529238ff8ff75066096a2adbd0a293c8ae592c21d1733a3\ns3transfer==0.19.3 --hash=sha256:24eb7535804306355e31c952a90022bf5b2f9d760f9a11062c7493a217c08553\njmespath==1.1.0 --hash=sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64\npython-dateutil==2.9.0.post0 --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427\nsix==1.17.0 --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274\nurllib3==2.8.0 --hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3\n",
|
|
3
|
+
"sources": [
|
|
4
|
+
{
|
|
5
|
+
"package": "boto3",
|
|
6
|
+
"version": "1.43.123",
|
|
7
|
+
"source": "https://pypi.org/pypi/boto3/1.43.123/json",
|
|
8
|
+
"wheels": [
|
|
9
|
+
{
|
|
10
|
+
"filename": "boto3-1.43.123-py3-none-any.whl",
|
|
11
|
+
"sha256": "d18d66e1e13faa0c25d0b1b8c5ce946e29fb5fc0b6456b655a93a678ff4cc313"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"package": "botocore",
|
|
17
|
+
"version": "1.43.123",
|
|
18
|
+
"source": "https://pypi.org/pypi/botocore/1.43.123/json",
|
|
19
|
+
"wheels": [
|
|
20
|
+
{
|
|
21
|
+
"filename": "botocore-1.43.123-py3-none-any.whl",
|
|
22
|
+
"sha256": "e30580f9c1282c321529238ff8ff75066096a2adbd0a293c8ae592c21d1733a3"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"package": "s3transfer",
|
|
28
|
+
"version": "0.19.3",
|
|
29
|
+
"source": "https://pypi.org/pypi/s3transfer/0.19.3/json",
|
|
30
|
+
"wheels": [
|
|
31
|
+
{
|
|
32
|
+
"filename": "s3transfer-0.19.3-py3-none-any.whl",
|
|
33
|
+
"sha256": "24eb7535804306355e31c952a90022bf5b2f9d760f9a11062c7493a217c08553"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"package": "jmespath",
|
|
39
|
+
"version": "1.1.0",
|
|
40
|
+
"source": "https://pypi.org/pypi/jmespath/1.1.0/json",
|
|
41
|
+
"wheels": [
|
|
42
|
+
{
|
|
43
|
+
"filename": "jmespath-1.1.0-py3-none-any.whl",
|
|
44
|
+
"sha256": "a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"package": "python-dateutil",
|
|
50
|
+
"version": "2.9.0.post0",
|
|
51
|
+
"source": "https://pypi.org/pypi/python-dateutil/2.9.0.post0/json",
|
|
52
|
+
"wheels": [
|
|
53
|
+
{
|
|
54
|
+
"filename": "python_dateutil-2.9.0.post0-py2.py3-none-any.whl",
|
|
55
|
+
"sha256": "a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"package": "six",
|
|
61
|
+
"version": "1.17.0",
|
|
62
|
+
"source": "https://pypi.org/pypi/six/1.17.0/json",
|
|
63
|
+
"wheels": [
|
|
64
|
+
{
|
|
65
|
+
"filename": "six-1.17.0-py2.py3-none-any.whl",
|
|
66
|
+
"sha256": "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"package": "urllib3",
|
|
72
|
+
"version": "2.8.0",
|
|
73
|
+
"source": "https://pypi.org/pypi/urllib3/2.8.0/json",
|
|
74
|
+
"wheels": [
|
|
75
|
+
{
|
|
76
|
+
"filename": "urllib3-2.8.0-py3-none-any.whl",
|
|
77
|
+
"sha256": "0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3"
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|