crca 1.4.0__py3-none-any.whl
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.
- .github/ISSUE_TEMPLATE/bug_report.md +65 -0
- .github/ISSUE_TEMPLATE/feature_request.md +41 -0
- .github/PULL_REQUEST_TEMPLATE.md +20 -0
- .github/workflows/publish-manual.yml +61 -0
- .github/workflows/publish.yml +64 -0
- .gitignore +214 -0
- CRCA.py +4156 -0
- LICENSE +201 -0
- MANIFEST.in +43 -0
- PKG-INFO +5035 -0
- README.md +4959 -0
- __init__.py +17 -0
- branches/CRCA-Q.py +2728 -0
- branches/crca_cg/corposwarm.py +9065 -0
- branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
- branches/crca_cg/package.json +5 -0
- branches/crca_cg/test_bolt_integration.py +446 -0
- branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
- branches/crca_cg/test_new_features.py +163 -0
- branches/crca_sd/__init__.py +149 -0
- branches/crca_sd/crca_sd_core.py +770 -0
- branches/crca_sd/crca_sd_governance.py +1325 -0
- branches/crca_sd/crca_sd_mpc.py +1130 -0
- branches/crca_sd/crca_sd_realtime.py +1844 -0
- branches/crca_sd/crca_sd_tui.py +1133 -0
- crca-1.4.0.dist-info/METADATA +5035 -0
- crca-1.4.0.dist-info/RECORD +501 -0
- crca-1.4.0.dist-info/WHEEL +4 -0
- crca-1.4.0.dist-info/licenses/LICENSE +201 -0
- docs/CRCA-Q.md +2333 -0
- examples/config.yaml.example +25 -0
- examples/crca_sd_example.py +513 -0
- examples/data_broker_example.py +294 -0
- examples/logistics_corporation.py +861 -0
- examples/palantir_example.py +299 -0
- examples/policy_bench.py +934 -0
- examples/pridnestrovia-sd.py +705 -0
- examples/pridnestrovia_realtime.py +1902 -0
- prompts/__init__.py +10 -0
- prompts/default_crca.py +101 -0
- pyproject.toml +151 -0
- requirements.txt +76 -0
- schemas/__init__.py +43 -0
- schemas/mcpSchemas.py +51 -0
- schemas/policy.py +458 -0
- templates/__init__.py +38 -0
- templates/base_specialized_agent.py +195 -0
- templates/drift_detection.py +325 -0
- templates/examples/causal_agent_template.py +309 -0
- templates/examples/drag_drop_example.py +213 -0
- templates/examples/logistics_agent_template.py +207 -0
- templates/examples/trading_agent_template.py +206 -0
- templates/feature_mixins.py +253 -0
- templates/graph_management.py +442 -0
- templates/llm_integration.py +194 -0
- templates/module_registry.py +276 -0
- templates/mpc_planner.py +280 -0
- templates/policy_loop.py +1168 -0
- templates/prediction_framework.py +448 -0
- templates/statistical_methods.py +778 -0
- tests/sanity.yml +31 -0
- tests/sanity_check +406 -0
- tests/test_core.py +47 -0
- tests/test_crca_excel.py +166 -0
- tests/test_crca_sd.py +780 -0
- tests/test_data_broker.py +424 -0
- tests/test_palantir.py +349 -0
- tools/__init__.py +38 -0
- tools/actuators.py +437 -0
- tools/bolt.diy/Dockerfile +103 -0
- tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
- tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
- tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
- tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
- tools/bolt.diy/app/components/@settings/index.ts +12 -0
- tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
- tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
- tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
- tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
- tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
- tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
- tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
- tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
- tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
- tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
- tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
- tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
- tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
- tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
- tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
- tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
- tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
- tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
- tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
- tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
- tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
- tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
- tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
- tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
- tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
- tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
- tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
- tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
- tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
- tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
- tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
- tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
- tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
- tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
- tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
- tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
- tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
- tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
- tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
- tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
- tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
- tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
- tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
- tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
- tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
- tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
- tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
- tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
- tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
- tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
- tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
- tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
- tools/bolt.diy/app/components/header/Header.tsx +42 -0
- tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
- tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
- tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
- tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
- tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
- tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
- tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
- tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
- tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
- tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
- tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
- tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
- tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
- tools/bolt.diy/app/components/txt +1 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
- tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
- tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
- tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
- tools/bolt.diy/app/components/ui/Button.tsx +46 -0
- tools/bolt.diy/app/components/ui/Card.tsx +55 -0
- tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
- tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
- tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
- tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
- tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
- tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
- tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
- tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
- tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
- tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
- tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
- tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
- tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
- tools/bolt.diy/app/components/ui/Input.tsx +22 -0
- tools/bolt.diy/app/components/ui/Label.tsx +20 -0
- tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
- tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
- tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
- tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
- tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
- tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
- tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
- tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
- tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
- tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
- tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
- tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
- tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
- tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
- tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
- tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
- tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
- tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
- tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
- tools/bolt.diy/app/components/ui/index.ts +38 -0
- tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
- tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
- tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
- tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
- tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
- tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
- tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
- tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
- tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
- tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
- tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
- tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
- tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
- tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
- tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
- tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
- tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
- tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
- tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
- tools/bolt.diy/app/entry.client.tsx +7 -0
- tools/bolt.diy/app/entry.server.tsx +80 -0
- tools/bolt.diy/app/root.tsx +156 -0
- tools/bolt.diy/app/routes/_index.tsx +175 -0
- tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
- tools/bolt.diy/app/routes/api.chat.ts +463 -0
- tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
- tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
- tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
- tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
- tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
- tools/bolt.diy/app/routes/api.git-info.ts +69 -0
- tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
- tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
- tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
- tools/bolt.diy/app/routes/api.github-template.ts +242 -0
- tools/bolt.diy/app/routes/api.github-user.ts +287 -0
- tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
- tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
- tools/bolt.diy/app/routes/api.health.ts +8 -0
- tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
- tools/bolt.diy/app/routes/api.mandate.ts +351 -0
- tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
- tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
- tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
- tools/bolt.diy/app/routes/api.models.ts +90 -0
- tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
- tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
- tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
- tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
- tools/bolt.diy/app/routes/api.supabase.ts +56 -0
- tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
- tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
- tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
- tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
- tools/bolt.diy/app/routes/api.update.ts +21 -0
- tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
- tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
- tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
- tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
- tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
- tools/bolt.diy/app/routes/git.tsx +25 -0
- tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
- tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
- tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
- tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
- tools/bolt.diy/app/styles/animations.scss +49 -0
- tools/bolt.diy/app/styles/components/code.scss +9 -0
- tools/bolt.diy/app/styles/components/editor.scss +135 -0
- tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
- tools/bolt.diy/app/styles/components/terminal.scss +3 -0
- tools/bolt.diy/app/styles/components/toast.scss +23 -0
- tools/bolt.diy/app/styles/diff-view.css +72 -0
- tools/bolt.diy/app/styles/index.scss +73 -0
- tools/bolt.diy/app/styles/variables.scss +255 -0
- tools/bolt.diy/app/styles/z-index.scss +37 -0
- tools/bolt.diy/app/types/GitHub.ts +182 -0
- tools/bolt.diy/app/types/GitLab.ts +103 -0
- tools/bolt.diy/app/types/actions.ts +85 -0
- tools/bolt.diy/app/types/artifact.ts +5 -0
- tools/bolt.diy/app/types/context.ts +26 -0
- tools/bolt.diy/app/types/design-scheme.ts +93 -0
- tools/bolt.diy/app/types/global.d.ts +13 -0
- tools/bolt.diy/app/types/mandate.ts +333 -0
- tools/bolt.diy/app/types/model.ts +25 -0
- tools/bolt.diy/app/types/netlify.ts +94 -0
- tools/bolt.diy/app/types/supabase.ts +54 -0
- tools/bolt.diy/app/types/template.ts +8 -0
- tools/bolt.diy/app/types/terminal.ts +9 -0
- tools/bolt.diy/app/types/theme.ts +1 -0
- tools/bolt.diy/app/types/vercel.ts +67 -0
- tools/bolt.diy/app/utils/buffer.ts +29 -0
- tools/bolt.diy/app/utils/classNames.ts +65 -0
- tools/bolt.diy/app/utils/constants.ts +147 -0
- tools/bolt.diy/app/utils/debounce.ts +13 -0
- tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
- tools/bolt.diy/app/utils/diff.spec.ts +11 -0
- tools/bolt.diy/app/utils/diff.ts +117 -0
- tools/bolt.diy/app/utils/easings.ts +3 -0
- tools/bolt.diy/app/utils/fileLocks.ts +96 -0
- tools/bolt.diy/app/utils/fileUtils.ts +121 -0
- tools/bolt.diy/app/utils/folderImport.ts +73 -0
- tools/bolt.diy/app/utils/formatSize.ts +12 -0
- tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
- tools/bolt.diy/app/utils/githubStats.ts +9 -0
- tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
- tools/bolt.diy/app/utils/logger.ts +162 -0
- tools/bolt.diy/app/utils/markdown.ts +155 -0
- tools/bolt.diy/app/utils/mobile.ts +4 -0
- tools/bolt.diy/app/utils/os.ts +4 -0
- tools/bolt.diy/app/utils/path.ts +19 -0
- tools/bolt.diy/app/utils/projectCommands.ts +197 -0
- tools/bolt.diy/app/utils/promises.ts +19 -0
- tools/bolt.diy/app/utils/react.ts +6 -0
- tools/bolt.diy/app/utils/sampler.ts +49 -0
- tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
- tools/bolt.diy/app/utils/shell.ts +384 -0
- tools/bolt.diy/app/utils/stacktrace.ts +27 -0
- tools/bolt.diy/app/utils/stripIndent.ts +23 -0
- tools/bolt.diy/app/utils/terminal.ts +11 -0
- tools/bolt.diy/app/utils/unreachable.ts +3 -0
- tools/bolt.diy/app/vite-env.d.ts +2 -0
- tools/bolt.diy/assets/entitlements.mac.plist +25 -0
- tools/bolt.diy/assets/icons/icon.icns +0 -0
- tools/bolt.diy/assets/icons/icon.ico +0 -0
- tools/bolt.diy/assets/icons/icon.png +0 -0
- tools/bolt.diy/bindings.js +78 -0
- tools/bolt.diy/bindings.sh +33 -0
- tools/bolt.diy/docker-compose.yaml +145 -0
- tools/bolt.diy/electron/main/index.ts +201 -0
- tools/bolt.diy/electron/main/tsconfig.json +30 -0
- tools/bolt.diy/electron/main/ui/menu.ts +29 -0
- tools/bolt.diy/electron/main/ui/window.ts +54 -0
- tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
- tools/bolt.diy/electron/main/utils/constants.ts +4 -0
- tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
- tools/bolt.diy/electron/main/utils/reload.ts +35 -0
- tools/bolt.diy/electron/main/utils/serve.ts +71 -0
- tools/bolt.diy/electron/main/utils/store.ts +3 -0
- tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
- tools/bolt.diy/electron/main/vite.config.ts +44 -0
- tools/bolt.diy/electron/preload/index.ts +22 -0
- tools/bolt.diy/electron/preload/tsconfig.json +7 -0
- tools/bolt.diy/electron/preload/vite.config.ts +31 -0
- tools/bolt.diy/electron-builder.yml +64 -0
- tools/bolt.diy/electron-update.yml +4 -0
- tools/bolt.diy/eslint.config.mjs +57 -0
- tools/bolt.diy/functions/[[path]].ts +12 -0
- tools/bolt.diy/icons/angular.svg +1 -0
- tools/bolt.diy/icons/astro.svg +8 -0
- tools/bolt.diy/icons/chat.svg +1 -0
- tools/bolt.diy/icons/expo-brand.svg +1 -0
- tools/bolt.diy/icons/expo.svg +4 -0
- tools/bolt.diy/icons/logo-text.svg +1 -0
- tools/bolt.diy/icons/logo.svg +4 -0
- tools/bolt.diy/icons/mcp.svg +1 -0
- tools/bolt.diy/icons/nativescript.svg +1 -0
- tools/bolt.diy/icons/netlify.svg +10 -0
- tools/bolt.diy/icons/nextjs.svg +1 -0
- tools/bolt.diy/icons/nuxt.svg +1 -0
- tools/bolt.diy/icons/qwik.svg +1 -0
- tools/bolt.diy/icons/react.svg +1 -0
- tools/bolt.diy/icons/remix.svg +24 -0
- tools/bolt.diy/icons/remotion.svg +1 -0
- tools/bolt.diy/icons/shadcn.svg +21 -0
- tools/bolt.diy/icons/slidev.svg +60 -0
- tools/bolt.diy/icons/solidjs.svg +1 -0
- tools/bolt.diy/icons/stars.svg +1 -0
- tools/bolt.diy/icons/svelte.svg +1 -0
- tools/bolt.diy/icons/typescript.svg +1 -0
- tools/bolt.diy/icons/vite.svg +1 -0
- tools/bolt.diy/icons/vue.svg +1 -0
- tools/bolt.diy/load-context.ts +9 -0
- tools/bolt.diy/notarize.cjs +31 -0
- tools/bolt.diy/package.json +218 -0
- tools/bolt.diy/playwright.config.preview.ts +35 -0
- tools/bolt.diy/pre-start.cjs +26 -0
- tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
- tools/bolt.diy/public/apple-touch-icon.png +0 -0
- tools/bolt.diy/public/favicon.ico +0 -0
- tools/bolt.diy/public/favicon.svg +4 -0
- tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
- tools/bolt.diy/public/icons/Anthropic.svg +4 -0
- tools/bolt.diy/public/icons/Cohere.svg +4 -0
- tools/bolt.diy/public/icons/Deepseek.svg +5 -0
- tools/bolt.diy/public/icons/Default.svg +4 -0
- tools/bolt.diy/public/icons/Google.svg +4 -0
- tools/bolt.diy/public/icons/Groq.svg +4 -0
- tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
- tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
- tools/bolt.diy/public/icons/LMStudio.svg +5 -0
- tools/bolt.diy/public/icons/Mistral.svg +4 -0
- tools/bolt.diy/public/icons/Ollama.svg +4 -0
- tools/bolt.diy/public/icons/OpenAI.svg +4 -0
- tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
- tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
- tools/bolt.diy/public/icons/Perplexity.svg +4 -0
- tools/bolt.diy/public/icons/Together.svg +4 -0
- tools/bolt.diy/public/icons/xAI.svg +5 -0
- tools/bolt.diy/public/inspector-script.js +292 -0
- tools/bolt.diy/public/logo-dark-styled.png +0 -0
- tools/bolt.diy/public/logo-dark.png +0 -0
- tools/bolt.diy/public/logo-light-styled.png +0 -0
- tools/bolt.diy/public/logo-light.png +0 -0
- tools/bolt.diy/public/logo.svg +15 -0
- tools/bolt.diy/public/social_preview_index.jpg +0 -0
- tools/bolt.diy/scripts/clean.js +45 -0
- tools/bolt.diy/scripts/electron-dev.mjs +181 -0
- tools/bolt.diy/scripts/setup-env.sh +41 -0
- tools/bolt.diy/scripts/update-imports.sh +7 -0
- tools/bolt.diy/scripts/update.sh +52 -0
- tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
- tools/bolt.diy/services/execution-governor/config.ts +42 -0
- tools/bolt.diy/services/execution-governor/index.ts +683 -0
- tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
- tools/bolt.diy/services/execution-governor/package.json +31 -0
- tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
- tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
- tools/bolt.diy/services/execution-governor/types.ts +145 -0
- tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
- tools/bolt.diy/services/headless-executor/executor.ts +210 -0
- tools/bolt.diy/services/headless-executor/index.ts +323 -0
- tools/bolt.diy/services/headless-executor/package.json +27 -0
- tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
- tools/bolt.diy/services/headless-executor/types.ts +38 -0
- tools/bolt.diy/test-workflows.sh +240 -0
- tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
- tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
- tools/bolt.diy/tests/mandates/complex.json +53 -0
- tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
- tools/bolt.diy/tests/mandates/simple.json +35 -0
- tools/bolt.diy/tsconfig.json +37 -0
- tools/bolt.diy/types/istextorbinary.d.ts +15 -0
- tools/bolt.diy/uno.config.ts +279 -0
- tools/bolt.diy/vite-electron.config.ts +76 -0
- tools/bolt.diy/vite.config.ts +112 -0
- tools/bolt.diy/worker-configuration.d.ts +22 -0
- tools/bolt.diy/wrangler.toml +6 -0
- tools/code_generator.py +461 -0
- tools/file_operations.py +465 -0
- tools/mandate_generator.py +337 -0
- tools/mcpClientUtils.py +1216 -0
- tools/sensors.py +285 -0
- utils/Agent_types.py +15 -0
- utils/AnyToStr.py +0 -0
- utils/HHCS.py +277 -0
- utils/__init__.py +30 -0
- utils/agent.py +3627 -0
- utils/aop.py +2948 -0
- utils/canonical.py +143 -0
- utils/conversation.py +1195 -0
- utils/doctrine_versioning +230 -0
- utils/formatter.py +474 -0
- utils/ledger.py +311 -0
- utils/out_types.py +16 -0
- utils/rollback.py +339 -0
- utils/router.py +929 -0
- utils/tui.py +1908 -0
tests/test_crca_sd.py
ADDED
|
@@ -0,0 +1,780 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for CRCA-SD components.
|
|
3
|
+
|
|
4
|
+
Tests cover:
|
|
5
|
+
- State vector initialization, validation, serialization
|
|
6
|
+
- Control vector sampling, simplex validation
|
|
7
|
+
- Dynamics model single-step and multi-step simulation
|
|
8
|
+
- Constraint checker for all constraint types
|
|
9
|
+
- Objective vector computation and aggregation
|
|
10
|
+
- CVaR computation accuracy
|
|
11
|
+
- MPC solver feasibility and optimality
|
|
12
|
+
- Scenario generation (Gaussian, structured)
|
|
13
|
+
- State estimation (EKF/UKF)
|
|
14
|
+
- Board evaluation and arbitration
|
|
15
|
+
- Logistics network flow optimization
|
|
16
|
+
- Integration tests for full workflows
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import pytest
|
|
20
|
+
import numpy as np
|
|
21
|
+
from typing import List, Dict
|
|
22
|
+
|
|
23
|
+
from crca_sd.crca_sd_core import (
|
|
24
|
+
StateVector,
|
|
25
|
+
ControlVector,
|
|
26
|
+
DynamicsModel,
|
|
27
|
+
ConstraintChecker,
|
|
28
|
+
ForwardSimulator,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
from crca_sd.crca_sd_mpc import (
|
|
32
|
+
ObjectiveVector,
|
|
33
|
+
CVaRComputer,
|
|
34
|
+
MPCSolver,
|
|
35
|
+
ScenarioGenerator,
|
|
36
|
+
StabilityEnforcer,
|
|
37
|
+
ParetoExtractor,
|
|
38
|
+
StateEstimator,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
from crca_sd.crca_sd_governance import (
|
|
42
|
+
BoardMember,
|
|
43
|
+
Board,
|
|
44
|
+
BoardType,
|
|
45
|
+
Arbitration,
|
|
46
|
+
GovernanceSystem,
|
|
47
|
+
LogisticsNetwork,
|
|
48
|
+
Visualization,
|
|
49
|
+
CRCA_SD_Config,
|
|
50
|
+
RiskAssessment,
|
|
51
|
+
MetricsCollector,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TestStateVector:
|
|
56
|
+
"""Test StateVector class."""
|
|
57
|
+
|
|
58
|
+
def test_initialization(self):
|
|
59
|
+
"""Test state vector initialization."""
|
|
60
|
+
x = StateVector()
|
|
61
|
+
assert x.P > 0
|
|
62
|
+
assert 0 <= x.U <= 1
|
|
63
|
+
assert 0 <= x.S <= 1
|
|
64
|
+
|
|
65
|
+
def test_validation(self):
|
|
66
|
+
"""Test state vector validation."""
|
|
67
|
+
x = StateVector()
|
|
68
|
+
is_valid, violations = x.validate()
|
|
69
|
+
assert is_valid
|
|
70
|
+
assert len(violations) == 0
|
|
71
|
+
|
|
72
|
+
# Test invalid state
|
|
73
|
+
x.U = 1.5 # Out of bounds
|
|
74
|
+
is_valid, violations = x.validate()
|
|
75
|
+
assert not is_valid
|
|
76
|
+
assert len(violations) > 0
|
|
77
|
+
|
|
78
|
+
def test_serialization(self):
|
|
79
|
+
"""Test state vector serialization."""
|
|
80
|
+
x = StateVector(P=1000000.0, U=0.05)
|
|
81
|
+
x_dict = x.to_dict()
|
|
82
|
+
assert x_dict["P"] == 1000000.0
|
|
83
|
+
assert x_dict["U"] == 0.05
|
|
84
|
+
|
|
85
|
+
x_restored = StateVector.from_dict(x_dict)
|
|
86
|
+
assert x_restored.P == x.P
|
|
87
|
+
assert x_restored.U == x.U
|
|
88
|
+
|
|
89
|
+
def test_copy(self):
|
|
90
|
+
"""Test state vector copying."""
|
|
91
|
+
x = StateVector(P=1000000.0)
|
|
92
|
+
x_copy = x.copy()
|
|
93
|
+
assert x_copy.P == x.P
|
|
94
|
+
x_copy.P = 2000000.0
|
|
95
|
+
assert x.P != x_copy.P # Deep copy
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class TestControlVector:
|
|
99
|
+
"""Test ControlVector class."""
|
|
100
|
+
|
|
101
|
+
def test_simplex_validation(self):
|
|
102
|
+
"""Test simplex constraint validation."""
|
|
103
|
+
u = ControlVector(budget_shares={"a": 0.5, "b": 0.5})
|
|
104
|
+
is_valid, error = u.validate_simplex()
|
|
105
|
+
assert is_valid
|
|
106
|
+
assert error is None
|
|
107
|
+
|
|
108
|
+
# Invalid: doesn't sum to 1
|
|
109
|
+
u = ControlVector(budget_shares={"a": 0.5, "b": 0.3})
|
|
110
|
+
is_valid, error = u.validate_simplex()
|
|
111
|
+
assert not is_valid
|
|
112
|
+
|
|
113
|
+
# Invalid: negative value
|
|
114
|
+
u = ControlVector(budget_shares={"a": 0.5, "b": -0.1, "c": 0.6})
|
|
115
|
+
is_valid, error = u.validate_simplex()
|
|
116
|
+
assert not is_valid
|
|
117
|
+
|
|
118
|
+
def test_dirichlet_sampling(self):
|
|
119
|
+
"""Test Dirichlet sampling for budget shares."""
|
|
120
|
+
categories = ["energy", "food", "infrastructure"]
|
|
121
|
+
u = ControlVector.sample_budget_simplex(categories)
|
|
122
|
+
is_valid, error = u.validate_simplex()
|
|
123
|
+
assert is_valid
|
|
124
|
+
assert all(cat in u.budget_shares for cat in categories)
|
|
125
|
+
|
|
126
|
+
def test_serialization(self):
|
|
127
|
+
"""Test control vector serialization."""
|
|
128
|
+
u = ControlVector(budget_shares={"a": 0.5, "b": 0.5})
|
|
129
|
+
u_dict = u.to_dict()
|
|
130
|
+
assert "budget_shares" in u_dict
|
|
131
|
+
|
|
132
|
+
u_restored = ControlVector.from_dict(u_dict)
|
|
133
|
+
assert u_restored.budget_shares == u.budget_shares
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TestDynamicsModel:
|
|
137
|
+
"""Test DynamicsModel class."""
|
|
138
|
+
|
|
139
|
+
def test_single_step(self):
|
|
140
|
+
"""Test single time step evolution."""
|
|
141
|
+
dynamics = DynamicsModel()
|
|
142
|
+
x_0 = StateVector()
|
|
143
|
+
u_0 = ControlVector.sample_budget_simplex(
|
|
144
|
+
["energy", "food", "infrastructure", "education"]
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
x_1 = dynamics.step(x_0, u_0)
|
|
148
|
+
|
|
149
|
+
assert isinstance(x_1, StateVector)
|
|
150
|
+
assert x_1.P >= 0
|
|
151
|
+
assert 0 <= x_1.U <= 1
|
|
152
|
+
|
|
153
|
+
def test_multi_step(self):
|
|
154
|
+
"""Test multi-step simulation."""
|
|
155
|
+
dynamics = DynamicsModel()
|
|
156
|
+
x_0 = StateVector()
|
|
157
|
+
u = ControlVector.sample_budget_simplex(
|
|
158
|
+
["energy", "food", "infrastructure"]
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
x_current = x_0
|
|
162
|
+
for _ in range(5):
|
|
163
|
+
x_current = dynamics.step(x_current, u)
|
|
164
|
+
assert isinstance(x_current, StateVector)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class TestConstraintChecker:
|
|
168
|
+
"""Test ConstraintChecker class."""
|
|
169
|
+
|
|
170
|
+
def test_feasibility_check(self):
|
|
171
|
+
"""Test constraint feasibility checking."""
|
|
172
|
+
checker = ConstraintChecker()
|
|
173
|
+
x = StateVector()
|
|
174
|
+
u = ControlVector.sample_budget_simplex(["energy", "food"])
|
|
175
|
+
|
|
176
|
+
is_feasible, violations = checker.check_feasible(x, u)
|
|
177
|
+
# Should be feasible with default state
|
|
178
|
+
assert isinstance(is_feasible, bool)
|
|
179
|
+
assert isinstance(violations, list)
|
|
180
|
+
|
|
181
|
+
def test_violations(self):
|
|
182
|
+
"""Test constraint violation detection."""
|
|
183
|
+
checker = ConstraintChecker()
|
|
184
|
+
x = StateVector(U=0.25) # Above U_max=0.2
|
|
185
|
+
u = ControlVector.sample_budget_simplex(["energy"])
|
|
186
|
+
|
|
187
|
+
is_feasible, violations = checker.check_feasible(x, u)
|
|
188
|
+
assert not is_feasible
|
|
189
|
+
assert len(violations) > 0
|
|
190
|
+
assert any("Unemployment" in v for v in violations)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class TestForwardSimulator:
|
|
194
|
+
"""Test ForwardSimulator class."""
|
|
195
|
+
|
|
196
|
+
def test_simulate_scenario(self):
|
|
197
|
+
"""Test scenario simulation."""
|
|
198
|
+
dynamics = DynamicsModel()
|
|
199
|
+
checker = ConstraintChecker()
|
|
200
|
+
simulator = ForwardSimulator(dynamics, checker)
|
|
201
|
+
|
|
202
|
+
x_0 = StateVector()
|
|
203
|
+
u = ControlVector.sample_budget_simplex(["energy", "food"])
|
|
204
|
+
disturbances = [{}] * 10
|
|
205
|
+
|
|
206
|
+
trajectory, feasibility_flags, first_violation = simulator.simulate_scenario(
|
|
207
|
+
x_0, u, disturbances, horizon=10
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
assert len(trajectory) == 11 # Initial + 10 steps
|
|
211
|
+
assert len(feasibility_flags) == 10
|
|
212
|
+
assert isinstance(first_violation, (int, type(None)))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class TestObjectiveVector:
|
|
216
|
+
"""Test ObjectiveVector class."""
|
|
217
|
+
|
|
218
|
+
def test_compute(self):
|
|
219
|
+
"""Test objective computation."""
|
|
220
|
+
obj_computer = ObjectiveVector(horizon=5)
|
|
221
|
+
|
|
222
|
+
trajectory = [StateVector() for _ in range(6)]
|
|
223
|
+
controls = [ControlVector() for _ in range(5)]
|
|
224
|
+
|
|
225
|
+
objectives = obj_computer.compute(trajectory, controls)
|
|
226
|
+
|
|
227
|
+
assert objectives.shape == (6,)
|
|
228
|
+
assert objectives[0] >= 0 # J_U (unemployment sum)
|
|
229
|
+
assert objectives[1] <= 0 # J_ℓ (negative literacy sum)
|
|
230
|
+
|
|
231
|
+
def test_aggregate(self):
|
|
232
|
+
"""Test objective aggregation across scenarios."""
|
|
233
|
+
obj_computer = ObjectiveVector()
|
|
234
|
+
|
|
235
|
+
scenarios = [
|
|
236
|
+
([StateVector() for _ in range(3)], [ControlVector() for _ in range(2)])
|
|
237
|
+
for _ in range(3)
|
|
238
|
+
]
|
|
239
|
+
|
|
240
|
+
expected_obj = obj_computer.aggregate(scenarios)
|
|
241
|
+
assert expected_obj.shape == (6,)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class TestCVaRComputer:
|
|
245
|
+
"""Test CVaRComputer class."""
|
|
246
|
+
|
|
247
|
+
def test_compute_cvar(self):
|
|
248
|
+
"""Test CVaR computation."""
|
|
249
|
+
cvar_computer = CVaRComputer(alpha=0.05)
|
|
250
|
+
|
|
251
|
+
z_scores = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
|
|
252
|
+
cvar = cvar_computer.compute_cvar(z_scores)
|
|
253
|
+
|
|
254
|
+
assert cvar >= 0
|
|
255
|
+
# CVaR should be >= mean of worst 5%
|
|
256
|
+
assert cvar >= np.mean(z_scores[-1:]) # Worst scenario
|
|
257
|
+
|
|
258
|
+
def test_collapse_proxy(self):
|
|
259
|
+
"""Test collapse proxy computation."""
|
|
260
|
+
cvar_computer = CVaRComputer()
|
|
261
|
+
|
|
262
|
+
trajectory = [StateVector(U=0.2, S=0.3)] # High U, low S
|
|
263
|
+
proxy = cvar_computer.collapse_proxy(trajectory)
|
|
264
|
+
|
|
265
|
+
assert proxy >= 0
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class TestScenarioGenerator:
|
|
269
|
+
"""Test ScenarioGenerator class."""
|
|
270
|
+
|
|
271
|
+
def test_gaussian_generation(self):
|
|
272
|
+
"""Test Gaussian scenario generation."""
|
|
273
|
+
generator = ScenarioGenerator()
|
|
274
|
+
|
|
275
|
+
scenarios = generator.generate_gaussian(n_scenarios=5, horizon=10)
|
|
276
|
+
|
|
277
|
+
assert len(scenarios) == 5
|
|
278
|
+
assert len(scenarios[0]) == 10
|
|
279
|
+
assert isinstance(scenarios[0][0], dict)
|
|
280
|
+
|
|
281
|
+
def test_structured_shock(self):
|
|
282
|
+
"""Test structured shock generation."""
|
|
283
|
+
generator = ScenarioGenerator()
|
|
284
|
+
|
|
285
|
+
scenario = generator.generate_structured_shock(
|
|
286
|
+
"trade_embargo", magnitude=0.5, timing=5, horizon=10
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
assert len(scenario) == 10
|
|
290
|
+
assert scenario[5].get("trade_shock", 0) > 0 # Shock at timing
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class TestStabilityEnforcer:
|
|
294
|
+
"""Test StabilityEnforcer class."""
|
|
295
|
+
|
|
296
|
+
def test_rate_limits(self):
|
|
297
|
+
"""Test rate limit application."""
|
|
298
|
+
enforcer = StabilityEnforcer(max_budget_change=0.1)
|
|
299
|
+
|
|
300
|
+
u_prev = ControlVector(budget_shares={"a": 0.5, "b": 0.5})
|
|
301
|
+
u_curr = ControlVector(budget_shares={"a": 0.9, "b": 0.1}) # Large change
|
|
302
|
+
|
|
303
|
+
u_adjusted = enforcer.apply_rate_limits(u_curr, u_prev)
|
|
304
|
+
|
|
305
|
+
# Check that change is limited
|
|
306
|
+
change = sum(abs(u_adjusted.budget_shares.get(k, 0) - u_prev.budget_shares.get(k, 0))
|
|
307
|
+
for k in set(list(u_adjusted.budget_shares.keys()) + list(u_prev.budget_shares.keys())))
|
|
308
|
+
assert change <= 0.1 + 1e-6 # Within limit
|
|
309
|
+
|
|
310
|
+
def test_investment_smoothing(self):
|
|
311
|
+
"""Test investment smoothing."""
|
|
312
|
+
enforcer = StabilityEnforcer(investment_smoothing=0.7)
|
|
313
|
+
|
|
314
|
+
I_hat = 100.0
|
|
315
|
+
I_prev = 50.0
|
|
316
|
+
|
|
317
|
+
I_smooth = enforcer.smooth_investment(I_hat, I_prev)
|
|
318
|
+
|
|
319
|
+
# Should be between I_prev and I_hat
|
|
320
|
+
assert I_prev <= I_smooth <= I_hat
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
class TestParetoExtractor:
|
|
324
|
+
"""Test ParetoExtractor class."""
|
|
325
|
+
|
|
326
|
+
def test_pareto_extraction(self):
|
|
327
|
+
"""Test Pareto frontier extraction."""
|
|
328
|
+
policies = [
|
|
329
|
+
ControlVector(budget_shares={"a": 0.5, "b": 0.5})
|
|
330
|
+
for _ in range(5)
|
|
331
|
+
]
|
|
332
|
+
|
|
333
|
+
# Create objective matrix (2 objectives)
|
|
334
|
+
objectives = np.array([
|
|
335
|
+
[1.0, 2.0], # Policy 0
|
|
336
|
+
[2.0, 1.0], # Policy 1 (dominated by 0? No, different objectives)
|
|
337
|
+
[0.5, 3.0], # Policy 2 (dominated by 0)
|
|
338
|
+
[3.0, 0.5], # Policy 3
|
|
339
|
+
[1.5, 1.5], # Policy 4
|
|
340
|
+
])
|
|
341
|
+
|
|
342
|
+
pareto_policies, pareto_obj = ParetoExtractor.extract_pareto_frontier(
|
|
343
|
+
policies, objectives
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
assert len(pareto_policies) <= len(policies)
|
|
347
|
+
assert pareto_obj.shape[0] == len(pareto_policies)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
class TestMPCSolver:
|
|
351
|
+
"""Test MPCSolver class."""
|
|
352
|
+
|
|
353
|
+
def test_solve(self):
|
|
354
|
+
"""Test MPC solver."""
|
|
355
|
+
dynamics = DynamicsModel()
|
|
356
|
+
checker = ConstraintChecker()
|
|
357
|
+
obj_computer = ObjectiveVector(horizon=5)
|
|
358
|
+
solver = MPCSolver(dynamics, checker, obj_computer, horizon=5)
|
|
359
|
+
|
|
360
|
+
x_t = StateVector()
|
|
361
|
+
scenarios = [[{}] * 5 for _ in range(3)]
|
|
362
|
+
|
|
363
|
+
policy, info = solver.solve(x_t, scenarios)
|
|
364
|
+
|
|
365
|
+
assert isinstance(policy, ControlVector)
|
|
366
|
+
assert "best_score" in info
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class TestBoard:
|
|
370
|
+
"""Test Board class."""
|
|
371
|
+
|
|
372
|
+
def test_preference_weights(self):
|
|
373
|
+
"""Test board preference weights."""
|
|
374
|
+
board = Board(
|
|
375
|
+
board_id="test",
|
|
376
|
+
board_type=BoardType.GROWTH,
|
|
377
|
+
members=[BoardMember(name="Test", board_type=BoardType.GROWTH)]
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
weights = board.get_preference_weights()
|
|
381
|
+
|
|
382
|
+
assert "J_Y" in weights
|
|
383
|
+
assert weights["J_Y"] > weights["J_C"] # Growth prioritizes output
|
|
384
|
+
|
|
385
|
+
def test_evaluate_policies(self):
|
|
386
|
+
"""Test policy evaluation."""
|
|
387
|
+
board = Board(
|
|
388
|
+
board_id="test",
|
|
389
|
+
board_type=BoardType.WELFARE,
|
|
390
|
+
members=[BoardMember(name="Test", board_type=BoardType.WELFARE)]
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
policies = [ControlVector.sample_budget_simplex(["a", "b"]) for _ in range(3)]
|
|
394
|
+
objectives = np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0] for _ in range(3)])
|
|
395
|
+
|
|
396
|
+
ranked = board.evaluate_policies(policies, objectives)
|
|
397
|
+
|
|
398
|
+
assert len(ranked) == len(policies)
|
|
399
|
+
assert ranked[0][1] <= ranked[-1][1] # Sorted by score
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
class TestArbitration:
|
|
403
|
+
"""Test Arbitration class."""
|
|
404
|
+
|
|
405
|
+
def test_weighted_vote(self):
|
|
406
|
+
"""Test weighted voting."""
|
|
407
|
+
boards = [
|
|
408
|
+
Board(
|
|
409
|
+
board_id=f"board_{i}",
|
|
410
|
+
board_type=BoardType.GROWTH,
|
|
411
|
+
members=[BoardMember(name=f"Member_{i}", board_type=BoardType.GROWTH, voting_weight=1.0)]
|
|
412
|
+
)
|
|
413
|
+
for i in range(2)
|
|
414
|
+
]
|
|
415
|
+
|
|
416
|
+
policies = [ControlVector.sample_budget_simplex(["a", "b"]) for _ in range(3)]
|
|
417
|
+
objectives = np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0] for _ in range(3)])
|
|
418
|
+
|
|
419
|
+
selected = Arbitration.weighted_vote(boards, policies, objectives)
|
|
420
|
+
|
|
421
|
+
assert selected is not None
|
|
422
|
+
assert selected in policies
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
class TestGovernanceSystem:
|
|
426
|
+
"""Test GovernanceSystem class."""
|
|
427
|
+
|
|
428
|
+
def test_select_policy(self):
|
|
429
|
+
"""Test policy selection."""
|
|
430
|
+
boards = [
|
|
431
|
+
Board(
|
|
432
|
+
board_id=f"board_{i}",
|
|
433
|
+
board_type=bt,
|
|
434
|
+
members=[BoardMember(name=f"Member_{i}", board_type=bt)]
|
|
435
|
+
)
|
|
436
|
+
for i, bt in enumerate([BoardType.GROWTH, BoardType.WELFARE])
|
|
437
|
+
]
|
|
438
|
+
|
|
439
|
+
governance = GovernanceSystem(boards, arbitration_method="weighted_vote")
|
|
440
|
+
|
|
441
|
+
policies = [ControlVector.sample_budget_simplex(["a", "b"]) for _ in range(3)]
|
|
442
|
+
objectives = np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0] for _ in range(3)])
|
|
443
|
+
|
|
444
|
+
selected = governance.select_policy(policies, objectives)
|
|
445
|
+
|
|
446
|
+
assert selected is not None
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
class TestLogisticsNetwork:
|
|
450
|
+
"""Test LogisticsNetwork class."""
|
|
451
|
+
|
|
452
|
+
def test_flow_problem(self):
|
|
453
|
+
"""Test flow optimization."""
|
|
454
|
+
nodes = ["A", "B", "C"]
|
|
455
|
+
edges = [("A", "B"), ("B", "C")]
|
|
456
|
+
network = LogisticsNetwork(nodes, edges)
|
|
457
|
+
|
|
458
|
+
demands = {"C": {"food": 100.0}}
|
|
459
|
+
commodities = ["food"]
|
|
460
|
+
|
|
461
|
+
flows = network.solve_flow_problem(demands, commodities)
|
|
462
|
+
|
|
463
|
+
assert isinstance(flows, dict)
|
|
464
|
+
# Should have flows for each edge-commodity pair
|
|
465
|
+
assert len(flows) > 0
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
class TestMetricsCollector:
|
|
469
|
+
"""Test MetricsCollector class."""
|
|
470
|
+
|
|
471
|
+
def test_compute_metrics(self):
|
|
472
|
+
"""Test metrics computation."""
|
|
473
|
+
collector = MetricsCollector()
|
|
474
|
+
|
|
475
|
+
trajectories = [[StateVector() for _ in range(3)] for _ in range(2)]
|
|
476
|
+
policies = [ControlVector() for _ in range(2)]
|
|
477
|
+
|
|
478
|
+
metrics = collector.compute_all_metrics(trajectories, policies)
|
|
479
|
+
|
|
480
|
+
assert "feasibility_rate" in metrics
|
|
481
|
+
assert "U_variance" in metrics
|
|
482
|
+
assert "control_effort" in metrics
|
|
483
|
+
|
|
484
|
+
def test_generate_report(self):
|
|
485
|
+
"""Test report generation."""
|
|
486
|
+
collector = MetricsCollector()
|
|
487
|
+
|
|
488
|
+
trajectories = [[StateVector() for _ in range(3)]]
|
|
489
|
+
policies = [ControlVector()]
|
|
490
|
+
collector.compute_all_metrics(trajectories, policies)
|
|
491
|
+
|
|
492
|
+
report = collector.generate_report()
|
|
493
|
+
assert isinstance(report, str)
|
|
494
|
+
assert "Metrics Report" in report
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
class TestIntegration:
|
|
498
|
+
"""Integration tests for full workflows."""
|
|
499
|
+
|
|
500
|
+
def test_full_simulation_workflow(self):
|
|
501
|
+
"""Test complete simulation workflow."""
|
|
502
|
+
# Initialize components
|
|
503
|
+
dynamics = DynamicsModel()
|
|
504
|
+
checker = ConstraintChecker()
|
|
505
|
+
simulator = ForwardSimulator(dynamics, checker)
|
|
506
|
+
|
|
507
|
+
# Initial state
|
|
508
|
+
x_0 = StateVector()
|
|
509
|
+
|
|
510
|
+
# Sample policy
|
|
511
|
+
u = ControlVector.sample_budget_simplex(
|
|
512
|
+
["energy", "food", "infrastructure", "education"]
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
# Simulate
|
|
516
|
+
trajectory, feasibility, first_violation = simulator.simulate_scenario(
|
|
517
|
+
x_0, u, [{}] * 10, horizon=10
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
assert len(trajectory) == 11
|
|
521
|
+
assert len(feasibility) == 10
|
|
522
|
+
|
|
523
|
+
def test_mpc_with_governance(self):
|
|
524
|
+
"""Test MPC solver with board governance."""
|
|
525
|
+
# Setup
|
|
526
|
+
dynamics = DynamicsModel()
|
|
527
|
+
checker = ConstraintChecker()
|
|
528
|
+
obj_computer = ObjectiveVector(horizon=5)
|
|
529
|
+
solver = MPCSolver(dynamics, checker, obj_computer, horizon=5)
|
|
530
|
+
simulator = ForwardSimulator(dynamics, checker)
|
|
531
|
+
|
|
532
|
+
# Create boards
|
|
533
|
+
boards = [
|
|
534
|
+
Board(
|
|
535
|
+
board_id=f"board_{i}",
|
|
536
|
+
board_type=bt,
|
|
537
|
+
members=[BoardMember(name=f"Member_{i}", board_type=bt)]
|
|
538
|
+
)
|
|
539
|
+
for i, bt in enumerate([BoardType.GROWTH, BoardType.WELFARE])
|
|
540
|
+
]
|
|
541
|
+
|
|
542
|
+
governance = GovernanceSystem(boards)
|
|
543
|
+
|
|
544
|
+
# Solve MPC
|
|
545
|
+
x_t = StateVector()
|
|
546
|
+
scenarios = [[{}] * 5 for _ in range(3)]
|
|
547
|
+
policy, _ = solver.solve(x_t, scenarios)
|
|
548
|
+
|
|
549
|
+
# Evaluate with boards
|
|
550
|
+
traj, _, _ = simulator.simulate_scenario(x_t, policy, scenarios[0], horizon=5)
|
|
551
|
+
objectives = obj_computer.compute(traj, [policy] * 5)
|
|
552
|
+
objectives_matrix = objectives.reshape(1, -1)
|
|
553
|
+
|
|
554
|
+
# Governance selection
|
|
555
|
+
selected = governance.select_policy([policy], objectives_matrix)
|
|
556
|
+
|
|
557
|
+
assert selected is not None
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
class TestRealTimeSystem:
|
|
561
|
+
"""Test real-time control system components."""
|
|
562
|
+
|
|
563
|
+
def test_data_acquisition(self):
|
|
564
|
+
"""Test data acquisition system."""
|
|
565
|
+
from crca_sd.crca_sd_realtime import DataAcquisition, DataSourceType
|
|
566
|
+
|
|
567
|
+
data_acq = DataAcquisition(update_frequency=3600.0) # 1 hour
|
|
568
|
+
|
|
569
|
+
# Connect to government API
|
|
570
|
+
success = data_acq.connect_government_api(
|
|
571
|
+
"treasury",
|
|
572
|
+
"https://api.example.gov/treasury",
|
|
573
|
+
{"api_key": "test"}
|
|
574
|
+
)
|
|
575
|
+
assert success
|
|
576
|
+
|
|
577
|
+
# Fetch data
|
|
578
|
+
data_points = data_acq.fetch_government_data(
|
|
579
|
+
"treasury",
|
|
580
|
+
"current_state",
|
|
581
|
+
["P", "U", "Y"]
|
|
582
|
+
)
|
|
583
|
+
|
|
584
|
+
assert len(data_points) > 0
|
|
585
|
+
assert data_points[0].source_type == DataSourceType.GOVERNMENT_API
|
|
586
|
+
|
|
587
|
+
def test_safety_interlocks(self):
|
|
588
|
+
"""Test safety interlock system."""
|
|
589
|
+
from crca_sd.crca_sd_realtime import SafetyInterlocks
|
|
590
|
+
|
|
591
|
+
safety = SafetyInterlocks(
|
|
592
|
+
major_change_threshold=0.10,
|
|
593
|
+
confidence_threshold=0.95
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
# Minor change policy
|
|
597
|
+
prev_policy = ControlVector(budget_shares={"a": 0.5, "b": 0.5})
|
|
598
|
+
minor_policy = ControlVector(budget_shares={"a": 0.55, "b": 0.45}) # 5% change
|
|
599
|
+
|
|
600
|
+
is_safe, reason, requires_approval = safety.check_policy_safety(
|
|
601
|
+
minor_policy,
|
|
602
|
+
prev_policy,
|
|
603
|
+
state_confidence=0.98
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
assert is_safe
|
|
607
|
+
assert not requires_approval # Minor change, automated
|
|
608
|
+
|
|
609
|
+
# Major change policy
|
|
610
|
+
major_policy = ControlVector(budget_shares={"a": 0.8, "b": 0.2}) # 30% change
|
|
611
|
+
|
|
612
|
+
is_safe, reason, requires_approval = safety.check_policy_safety(
|
|
613
|
+
major_policy,
|
|
614
|
+
prev_policy,
|
|
615
|
+
state_confidence=0.98
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
assert is_safe
|
|
619
|
+
assert requires_approval # Major change, needs approval
|
|
620
|
+
|
|
621
|
+
def test_policy_executor(self):
|
|
622
|
+
"""Test policy executor."""
|
|
623
|
+
from crca_sd.crca_sd_realtime import PolicyExecutor
|
|
624
|
+
|
|
625
|
+
executor = PolicyExecutor()
|
|
626
|
+
|
|
627
|
+
policy = ControlVector.sample_budget_simplex(["energy", "food"])
|
|
628
|
+
success, message, info = executor.execute_policy(policy)
|
|
629
|
+
|
|
630
|
+
assert isinstance(success, bool)
|
|
631
|
+
assert "execution_id" in info
|
|
632
|
+
|
|
633
|
+
def test_governance_approval(self):
|
|
634
|
+
"""Test governance approval workflow."""
|
|
635
|
+
from crca_sd.crca_sd_governance import GovernanceSystem, Board, BoardType, BoardMember
|
|
636
|
+
|
|
637
|
+
boards = [
|
|
638
|
+
Board(
|
|
639
|
+
board_id="test",
|
|
640
|
+
board_type=BoardType.GROWTH,
|
|
641
|
+
members=[BoardMember(name="Test", board_type=BoardType.GROWTH)]
|
|
642
|
+
)
|
|
643
|
+
]
|
|
644
|
+
|
|
645
|
+
governance = GovernanceSystem(boards, major_change_threshold=0.10)
|
|
646
|
+
|
|
647
|
+
# Minor change
|
|
648
|
+
prev = ControlVector(budget_shares={"a": 0.5, "b": 0.5})
|
|
649
|
+
minor = ControlVector(budget_shares={"a": 0.55, "b": 0.45})
|
|
650
|
+
|
|
651
|
+
requires, reason = governance.requires_approval(minor, prev)
|
|
652
|
+
assert not requires
|
|
653
|
+
|
|
654
|
+
# Major change
|
|
655
|
+
major = ControlVector(budget_shares={"a": 0.8, "b": 0.2})
|
|
656
|
+
requires, reason = governance.requires_approval(major, prev)
|
|
657
|
+
assert requires
|
|
658
|
+
|
|
659
|
+
# Request approval
|
|
660
|
+
approval_id = governance.request_approval(major, reason, "system")
|
|
661
|
+
assert approval_id in governance.pending_approvals
|
|
662
|
+
|
|
663
|
+
# Approve
|
|
664
|
+
success, message = governance.approve_policy(approval_id, "human", "Approved")
|
|
665
|
+
assert success
|
|
666
|
+
|
|
667
|
+
def test_rollback_system(self):
|
|
668
|
+
"""Test rollback system (7-day window)."""
|
|
669
|
+
from crca_sd.crca_sd_realtime import RollbackSystem
|
|
670
|
+
|
|
671
|
+
rollback = RollbackSystem(rollback_window_days=7)
|
|
672
|
+
|
|
673
|
+
# Create snapshots
|
|
674
|
+
state1 = StateVector(P=360000.0)
|
|
675
|
+
state2 = StateVector(P=361000.0)
|
|
676
|
+
|
|
677
|
+
snap1 = rollback.create_snapshot(state1)
|
|
678
|
+
snap2 = rollback.create_snapshot(state2)
|
|
679
|
+
|
|
680
|
+
assert snap1 != snap2
|
|
681
|
+
|
|
682
|
+
# Record policy
|
|
683
|
+
policy = ControlVector()
|
|
684
|
+
rollback.record_policy_execution(policy, "exec_1")
|
|
685
|
+
|
|
686
|
+
# Rollback
|
|
687
|
+
rolled = rollback.rollback_policies(1)
|
|
688
|
+
assert len(rolled) == 1
|
|
689
|
+
assert rolled[0] == "exec_1"
|
|
690
|
+
|
|
691
|
+
# Restore state
|
|
692
|
+
restored = rollback.restore_state()
|
|
693
|
+
assert restored is not None
|
|
694
|
+
assert restored.P == state2.P
|
|
695
|
+
|
|
696
|
+
def test_compliance_system(self):
|
|
697
|
+
"""Test compliance system."""
|
|
698
|
+
from crca_sd.crca_sd_realtime import ComplianceSystem
|
|
699
|
+
|
|
700
|
+
compliance = ComplianceSystem()
|
|
701
|
+
|
|
702
|
+
# Log decision
|
|
703
|
+
log_id = compliance.log_decision(
|
|
704
|
+
"policy_execution",
|
|
705
|
+
{"policy": "test"},
|
|
706
|
+
"user1",
|
|
707
|
+
"Test decision",
|
|
708
|
+
approved_by=["user2"]
|
|
709
|
+
)
|
|
710
|
+
|
|
711
|
+
assert log_id is not None
|
|
712
|
+
|
|
713
|
+
# Get audit trail
|
|
714
|
+
trail = compliance.get_audit_trail(user_id="user1")
|
|
715
|
+
assert len(trail) > 0
|
|
716
|
+
|
|
717
|
+
def test_alerting_system(self):
|
|
718
|
+
"""Test alerting system."""
|
|
719
|
+
from crca_sd.crca_sd_realtime import AlertingSystem, AlertLevel
|
|
720
|
+
|
|
721
|
+
alerting = AlertingSystem()
|
|
722
|
+
|
|
723
|
+
# Create alerts
|
|
724
|
+
alert1 = alerting.create_alert(
|
|
725
|
+
AlertLevel.INFO,
|
|
726
|
+
"Test alert",
|
|
727
|
+
"monitor"
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
alert2 = alerting.create_alert(
|
|
731
|
+
AlertLevel.CRITICAL,
|
|
732
|
+
"Critical issue",
|
|
733
|
+
"safety"
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
assert alert1 is not None
|
|
737
|
+
assert alert2 is not None
|
|
738
|
+
|
|
739
|
+
# Get unacknowledged
|
|
740
|
+
unack = alerting.get_unacknowledged_alerts()
|
|
741
|
+
assert len(unack) >= 2
|
|
742
|
+
|
|
743
|
+
def test_realtime_integration(self):
|
|
744
|
+
"""Test integration of real-time components."""
|
|
745
|
+
from crca_sd.crca_sd_realtime import (
|
|
746
|
+
DataAcquisition,
|
|
747
|
+
RealTimeStateEstimator,
|
|
748
|
+
RealTimeMonitor,
|
|
749
|
+
PolicyExecutor,
|
|
750
|
+
SafetyInterlocks,
|
|
751
|
+
)
|
|
752
|
+
|
|
753
|
+
# Setup
|
|
754
|
+
dynamics = DynamicsModel()
|
|
755
|
+
checker = ConstraintChecker()
|
|
756
|
+
|
|
757
|
+
data_acq = DataAcquisition()
|
|
758
|
+
state_estimator = RealTimeStateEstimator(dynamics)
|
|
759
|
+
monitor = RealTimeMonitor(checker)
|
|
760
|
+
executor = PolicyExecutor()
|
|
761
|
+
safety = SafetyInterlocks()
|
|
762
|
+
|
|
763
|
+
# Test workflow
|
|
764
|
+
x_t = StateVector()
|
|
765
|
+
policy = ControlVector.sample_budget_simplex(["energy", "food"])
|
|
766
|
+
|
|
767
|
+
# Check safety
|
|
768
|
+
is_safe, reason, requires_approval = safety.check_policy_safety(
|
|
769
|
+
policy,
|
|
770
|
+
None,
|
|
771
|
+
state_confidence=0.98
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
assert isinstance(is_safe, bool)
|
|
775
|
+
|
|
776
|
+
# Execute if safe
|
|
777
|
+
if is_safe and not requires_approval:
|
|
778
|
+
success, message, info = executor.execute_policy(policy)
|
|
779
|
+
assert isinstance(success, bool)
|
|
780
|
+
|