ciris-agent 1.7.7__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.
- ciris_adapters/README.md +113 -0
- ciris_adapters/__init__.py +30 -0
- ciris_adapters/ciris_covenant_metrics/README.md +144 -0
- ciris_adapters/ciris_covenant_metrics/__init__.py +36 -0
- ciris_adapters/ciris_covenant_metrics/adapter.py +249 -0
- ciris_adapters/ciris_covenant_metrics/manifest.json +152 -0
- ciris_adapters/ciris_covenant_metrics/services.py +403 -0
- ciris_adapters/ciris_hosted_tools/__init__.py +24 -0
- ciris_adapters/ciris_hosted_tools/adapter.py +169 -0
- ciris_adapters/ciris_hosted_tools/manifest.json +94 -0
- ciris_adapters/ciris_hosted_tools/services.py +744 -0
- ciris_adapters/external_data_sql/README.md +559 -0
- ciris_adapters/external_data_sql/__init__.py +43 -0
- ciris_adapters/external_data_sql/adapter.py +144 -0
- ciris_adapters/external_data_sql/configurable.py +315 -0
- ciris_adapters/external_data_sql/dialects/__init__.py +37 -0
- ciris_adapters/external_data_sql/dialects/base.py +133 -0
- ciris_adapters/external_data_sql/dialects/mysql.py +63 -0
- ciris_adapters/external_data_sql/dialects/postgresql.py +59 -0
- ciris_adapters/external_data_sql/dialects/sqlite.py +62 -0
- ciris_adapters/external_data_sql/example_config.json +88 -0
- ciris_adapters/external_data_sql/example_privacy_schema.yaml +127 -0
- ciris_adapters/external_data_sql/manifest.json +195 -0
- ciris_adapters/external_data_sql/privacy_schema_loader.py +189 -0
- ciris_adapters/external_data_sql/protocol.py +101 -0
- ciris_adapters/external_data_sql/schemas.py +146 -0
- ciris_adapters/external_data_sql/service.py +1547 -0
- ciris_adapters/external_data_sql/service_old.py +492 -0
- ciris_adapters/home_assistant/__init__.py +63 -0
- ciris_adapters/home_assistant/adapter.py +201 -0
- ciris_adapters/home_assistant/communication_service.py +347 -0
- ciris_adapters/home_assistant/configurable.py +667 -0
- ciris_adapters/home_assistant/manifest.json +203 -0
- ciris_adapters/home_assistant/schemas.py +129 -0
- ciris_adapters/home_assistant/service.py +751 -0
- ciris_adapters/home_assistant/tool_service.py +441 -0
- ciris_adapters/mcp_client/__init__.py +82 -0
- ciris_adapters/mcp_client/adapter.py +847 -0
- ciris_adapters/mcp_client/config.py +280 -0
- ciris_adapters/mcp_client/configurable.py +422 -0
- ciris_adapters/mcp_client/manifest.json +185 -0
- ciris_adapters/mcp_client/mcp_communication_service.py +393 -0
- ciris_adapters/mcp_client/mcp_tool_service.py +463 -0
- ciris_adapters/mcp_client/mcp_wise_service.py +394 -0
- ciris_adapters/mcp_client/schemas.py +149 -0
- ciris_adapters/mcp_client/security.py +592 -0
- ciris_adapters/mcp_common/__init__.py +44 -0
- ciris_adapters/mcp_common/manifest.json +25 -0
- ciris_adapters/mcp_common/protocol.py +315 -0
- ciris_adapters/mcp_common/schemas.py +225 -0
- ciris_adapters/mcp_server/__init__.py +47 -0
- ciris_adapters/mcp_server/adapter.py +581 -0
- ciris_adapters/mcp_server/config.py +260 -0
- ciris_adapters/mcp_server/configurable.py +393 -0
- ciris_adapters/mcp_server/handlers.py +663 -0
- ciris_adapters/mcp_server/manifest.json +211 -0
- ciris_adapters/mcp_server/security.py +500 -0
- ciris_adapters/mock_llm/README.md +117 -0
- ciris_adapters/mock_llm/__init__.py +21 -0
- ciris_adapters/mock_llm/adapter.py +131 -0
- ciris_adapters/mock_llm/configurable.py +237 -0
- ciris_adapters/mock_llm/manifest.json +106 -0
- ciris_adapters/mock_llm/protocol.py +37 -0
- ciris_adapters/mock_llm/responses.py +520 -0
- ciris_adapters/mock_llm/responses_action_selection.py +1041 -0
- ciris_adapters/mock_llm/responses_epistemic.py +17 -0
- ciris_adapters/mock_llm/responses_feedback.py +27 -0
- ciris_adapters/mock_llm/schemas.py +35 -0
- ciris_adapters/mock_llm/service.py +294 -0
- ciris_adapters/navigation/__init__.py +21 -0
- ciris_adapters/navigation/adapter.py +129 -0
- ciris_adapters/navigation/configurable.py +239 -0
- ciris_adapters/navigation/manifest.json +104 -0
- ciris_adapters/navigation/service.py +487 -0
- ciris_adapters/reddit/README.md +132 -0
- ciris_adapters/reddit/REDDIT_ADAPTER_ANALYSIS.md +715 -0
- ciris_adapters/reddit/REDDIT_ADAPTER_SUMMARY.txt +278 -0
- ciris_adapters/reddit/REDDIT_ANALYSIS_INDEX.md +307 -0
- ciris_adapters/reddit/REDDIT_PRODUCTION_READINESS_PLAN.md +518 -0
- ciris_adapters/reddit/__init__.py +15 -0
- ciris_adapters/reddit/adapter.py +189 -0
- ciris_adapters/reddit/configurable.py +274 -0
- ciris_adapters/reddit/error_handler.py +307 -0
- ciris_adapters/reddit/manifest.json +218 -0
- ciris_adapters/reddit/observer.py +532 -0
- ciris_adapters/reddit/protocol.py +34 -0
- ciris_adapters/reddit/schemas.py +433 -0
- ciris_adapters/reddit/service.py +1471 -0
- ciris_adapters/sample_adapter/README.md +474 -0
- ciris_adapters/sample_adapter/__init__.py +45 -0
- ciris_adapters/sample_adapter/adapter.py +208 -0
- ciris_adapters/sample_adapter/configurable.py +469 -0
- ciris_adapters/sample_adapter/manifest.json +247 -0
- ciris_adapters/sample_adapter/services.py +486 -0
- ciris_adapters/weather/__init__.py +16 -0
- ciris_adapters/weather/adapter.py +130 -0
- ciris_adapters/weather/configurable.py +240 -0
- ciris_adapters/weather/manifest.json +156 -0
- ciris_adapters/weather/service.py +600 -0
- ciris_agent-1.7.7.dist-info/METADATA +284 -0
- ciris_agent-1.7.7.dist-info/RECORD +986 -0
- ciris_agent-1.7.7.dist-info/WHEEL +5 -0
- ciris_agent-1.7.7.dist-info/entry_points.txt +15 -0
- ciris_agent-1.7.7.dist-info/licenses/LICENSE +205 -0
- ciris_agent-1.7.7.dist-info/licenses/NOTICE +82 -0
- ciris_agent-1.7.7.dist-info/top_level.txt +4 -0
- ciris_engine/__init__.py +15 -0
- ciris_engine/ciris_templates/ally.yaml +632 -0
- ciris_engine/ciris_templates/default.yaml +411 -0
- ciris_engine/ciris_templates/echo-core.yaml +629 -0
- ciris_engine/ciris_templates/echo-speculative.yaml +764 -0
- ciris_engine/ciris_templates/echo.yaml +647 -0
- ciris_engine/ciris_templates/sage.yaml +332 -0
- ciris_engine/ciris_templates/scout.yaml +338 -0
- ciris_engine/ciris_templates/test.yaml +168 -0
- ciris_engine/cli.py +42 -0
- ciris_engine/config/CIRIS_SERVICES.json +19 -0
- ciris_engine/config/MODEL_CAPABILITIES.json +419 -0
- ciris_engine/config/PRICING_DATA.json +179 -0
- ciris_engine/config/__init__.py +50 -0
- ciris_engine/config/ciris_services.py +113 -0
- ciris_engine/config/model_capabilities.py +388 -0
- ciris_engine/config/pricing_models.py +276 -0
- ciris_engine/constants.py +35 -0
- ciris_engine/data/__init__.py +1 -0
- ciris_engine/data/covenant_1.0b.txt +978 -0
- ciris_engine/gui_static/11steps.svg +107 -0
- ciris_engine/gui_static/2x-schematics.png +0 -0
- ciris_engine/gui_static/404/index.html +1 -0
- ciris_engine/gui_static/404.html +1 -0
- ciris_engine/gui_static/_next/static/0edhkwDxd5UccTsCmtaBi/_buildManifest.js +1 -0
- ciris_engine/gui_static/_next/static/0edhkwDxd5UccTsCmtaBi/_ssgManifest.js +1 -0
- ciris_engine/gui_static/_next/static/U-3xTQao7hc2wnAi-Uekm/_buildManifest.js +1 -0
- ciris_engine/gui_static/_next/static/U-3xTQao7hc2wnAi-Uekm/_ssgManifest.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/3297-60e86ba0f8a7b040.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/3835-2aad4b7f5f8e4643.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4499-99a0bc47de0b8975.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4534-af88cd4ba6e99bff.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4541-84b455f9e0dc4cfe.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4789-61412711484754bb.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/6539-c6398bc9d7018430.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/704-8e827b26cc8c2d32.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/704-fb45d630f3192c6f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8072-de4952a2e6d2b33f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8315-b91d03a3949db0af.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8386-f93a83ccbd789bd9.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/87c73c54-781a7f35148d5433.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8903-fefea3339a02d41b.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/9090-e66485adf8d9d990.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/_not-found/page-a67d9808462c23b1.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/api-keys/page-2d7ee1583bbbd02e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/api-keys/page-6a3c2bae6fe92b7b.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/consent/page-2ed3a035136bc4e8.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/consent/page-b2f5c91844a32422.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/page-25b90f89af3ea58c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/page-b65d16c94ecaf69c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/privacy/page-675b6d05c8f9184f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/privacy/page-cbee2e1c8ab52145.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/settings/page-0f44da06697cf9f0.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/settings/page-563420253577edbf.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/adapters/page-1854631018bc32be.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/agents/page-8353752c176a7c70.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/agents/page-f61a529f110a6040.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/api-demo/page-7f19b9d20d39be28.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/api-demo/page-d1063938f249b8bd.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/audit/page-321b6728b8fff0bb.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/audit/page-ebac35ca961a1277.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/billing/page-6f3dc3bd02924f8e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/billing/page-fa4a469f814c821a.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/comms/page-0d4f734269addd8f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/comms/page-79227d426050089c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/config/page-018d21d683b6e5bc.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/config/page-2aa5a5363ca2a371.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/consent/page-198373205fd316e2.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/consent/page-f2ca39e7713b13f8.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/dashboard/page-1dd5a196f643c60d.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/dashboard/page-530a04d3abbb8cda.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/docs/page-3193b06d094ab654.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/docs/page-330e996dedb87aba.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/layout-0a70f5fc460298b1.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/layout-21f2f99dd5b336e9.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/login/page-33240e6c6034a49d.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/login/page-68ffab6d54a7fdcd.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/logs/page-8a6167aecc4a475c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/memory/page-9ca8c5d0056de3ff.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/memory/page-e961226941c18f81.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/page-6fdb065a787a4974.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/page-89f87d431be6064a.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/runtime/page-2e728b9c43aa164d.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/runtime/page-c7dd033dc40a72f0.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/services/page-ae9f0bdf11d01a95.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/services/page-b10feb79ca5d75e5.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/sessions/page-13ebe7ef1c16ae11.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/sessions/page-e6c82b16d617f785.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/setup/page-0beb5f5b5a5c20fc.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/setup/page-2595e729eae30c0e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/status-dashboard/page-1037c987aecc3653.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/status-dashboard/page-2ffd147f6d3162ff.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/system/page-2c5798d58cafcd91.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/system/page-505b1ba4eceb01c3.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-auth/page-b0cad31d5cb1b2fa.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-auth/page-f3ecd7a8012df230.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-login/page-f35117fdc4105801.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-login/page-fb583a7924114906.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-sdk/page-50f116fd76935563.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-sdk/page-c37d8aa5ba623a44.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/tools/page-429aec7a707777ef.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/tools/page-5f705aad60e0c04e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/users/page-13476b8b0f3808cc.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/users/page-7e500d154ed5bba4.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/wa/page-cc4a9d8a5cb44d08.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/wa/page-ec3e429efbc79230.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/framework-9d29490f5ba089ba.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/main-1f554952e47a82c4.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/main-app-26fa8aed029082e5.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/main-app-97b0486ef6bcef25.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/pages/_app-6ce685456e616eb2.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/pages/_error-d4bce98d93fe21e7.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/webpack-fcebd240b7f8477d.js +1 -0
- ciris_engine/gui_static/_next/static/css/16b94b1fe0cc6e37.css +3 -0
- ciris_engine/gui_static/_next/static/css/77a24ceaae86deff.css +3 -0
- ciris_engine/gui_static/_next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/747892c23ea88013-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/8d697b304b401681-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/9610d9e46709d722-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/d8298875641ec7d4-s.p.woff2 +0 -0
- ciris_engine/gui_static/account/api-keys/index.html +1 -0
- ciris_engine/gui_static/account/api-keys/index.txt +27 -0
- ciris_engine/gui_static/account/consent/index.html +1 -0
- ciris_engine/gui_static/account/consent/index.txt +27 -0
- ciris_engine/gui_static/account/index.html +1 -0
- ciris_engine/gui_static/account/index.txt +27 -0
- ciris_engine/gui_static/account/privacy/index.html +1 -0
- ciris_engine/gui_static/account/privacy/index.txt +27 -0
- ciris_engine/gui_static/account/settings/index.html +1 -0
- ciris_engine/gui_static/account/settings/index.txt +27 -0
- ciris_engine/gui_static/adapters/index.html +1 -0
- ciris_engine/gui_static/adapters/index.txt +27 -0
- ciris_engine/gui_static/agents/index.html +1 -0
- ciris_engine/gui_static/agents/index.txt +27 -0
- ciris_engine/gui_static/andrew-roberts-euBRXcx57T4-unsplash.jpg +0 -0
- ciris_engine/gui_static/api-demo/index.html +1 -0
- ciris_engine/gui_static/api-demo/index.txt +27 -0
- ciris_engine/gui_static/audit/index.html +1 -0
- ciris_engine/gui_static/audit/index.txt +27 -0
- ciris_engine/gui_static/billing/index.html +1 -0
- ciris_engine/gui_static/billing/index.txt +27 -0
- ciris_engine/gui_static/blurryinfo.png +0 -0
- ciris_engine/gui_static/chip-vincent-PkQDwfl9Flc-unsplash.jpg +0 -0
- ciris_engine/gui_static/ciris-architecture.svg +338 -0
- ciris_engine/gui_static/comms/index.html +1 -0
- ciris_engine/gui_static/comms/index.txt +27 -0
- ciris_engine/gui_static/config/index.html +1 -0
- ciris_engine/gui_static/config/index.txt +27 -0
- ciris_engine/gui_static/consent/index.html +1 -0
- ciris_engine/gui_static/consent/index.txt +27 -0
- ciris_engine/gui_static/dashboard/index.html +1 -0
- ciris_engine/gui_static/dashboard/index.txt +27 -0
- ciris_engine/gui_static/docs/index.html +1 -0
- ciris_engine/gui_static/docs/index.txt +27 -0
- ciris_engine/gui_static/eric.png +0 -0
- ciris_engine/gui_static/file.svg +1 -0
- ciris_engine/gui_static/globe.svg +1 -0
- ciris_engine/gui_static/index.html +1 -0
- ciris_engine/gui_static/index.txt +27 -0
- ciris_engine/gui_static/infogfx-1@2x.png +0 -0
- ciris_engine/gui_static/infogfx-2.png +0 -0
- ciris_engine/gui_static/infogfx-dark-1.png +0 -0
- ciris_engine/gui_static/kelly-vohs-soSTXmIxTDU-unsplash.jpg +0 -0
- ciris_engine/gui_static/login/index.html +1 -0
- ciris_engine/gui_static/login/index.txt +27 -0
- ciris_engine/gui_static/logs/index.html +1 -0
- ciris_engine/gui_static/logs/index.txt +27 -0
- ciris_engine/gui_static/memory/index.html +1 -0
- ciris_engine/gui_static/memory/index.txt +27 -0
- ciris_engine/gui_static/nathan-farrish-ArcTfEoBgzs-unsplash.jpg +0 -0
- ciris_engine/gui_static/next.svg +1 -0
- ciris_engine/gui_static/overview.svg +512 -0
- ciris_engine/gui_static/overview1.svg +407 -0
- ciris_engine/gui_static/overview2.svg +370 -0
- ciris_engine/gui_static/pipeline-visualization.svg +278 -0
- ciris_engine/gui_static/privacy-policy.html +160 -0
- ciris_engine/gui_static/runtime/index.html +8 -0
- ciris_engine/gui_static/runtime/index.txt +27 -0
- ciris_engine/gui_static/services/index.html +1 -0
- ciris_engine/gui_static/services/index.txt +27 -0
- ciris_engine/gui_static/sessions/index.html +1 -0
- ciris_engine/gui_static/sessions/index.txt +27 -0
- ciris_engine/gui_static/setup/index.html +1 -0
- ciris_engine/gui_static/setup/index.txt +27 -0
- ciris_engine/gui_static/status-dashboard/index.html +1 -0
- ciris_engine/gui_static/status-dashboard/index.txt +27 -0
- ciris_engine/gui_static/system/index.html +1 -0
- ciris_engine/gui_static/system/index.txt +27 -0
- ciris_engine/gui_static/terms-of-service.html +174 -0
- ciris_engine/gui_static/test-auth/index.html +1 -0
- ciris_engine/gui_static/test-auth/index.txt +27 -0
- ciris_engine/gui_static/test-login/index.html +1 -0
- ciris_engine/gui_static/test-login/index.txt +27 -0
- ciris_engine/gui_static/test-sdk/index.html +1 -0
- ciris_engine/gui_static/test-sdk/index.txt +27 -0
- ciris_engine/gui_static/tools/index.html +1 -0
- ciris_engine/gui_static/tools/index.txt +27 -0
- ciris_engine/gui_static/users/index.html +1 -0
- ciris_engine/gui_static/users/index.txt +27 -0
- ciris_engine/gui_static/vercel.svg +1 -0
- ciris_engine/gui_static/videos/video1.mp4 +0 -0
- ciris_engine/gui_static/videos/video3.mp4 +0 -0
- ciris_engine/gui_static/wa/index.html +1 -0
- ciris_engine/gui_static/wa/index.txt +27 -0
- ciris_engine/gui_static/window.svg +1 -0
- ciris_engine/logic/__init__.py +8 -0
- ciris_engine/logic/adapters/__init__.py +74 -0
- ciris_engine/logic/adapters/api/__init__.py +5 -0
- ciris_engine/logic/adapters/api/adapter.py +1037 -0
- ciris_engine/logic/adapters/api/api_communication.py +370 -0
- ciris_engine/logic/adapters/api/api_document.py +330 -0
- ciris_engine/logic/adapters/api/api_observer.py +24 -0
- ciris_engine/logic/adapters/api/api_runtime_control.py +388 -0
- ciris_engine/logic/adapters/api/api_tools.py +299 -0
- ciris_engine/logic/adapters/api/api_vision.py +215 -0
- ciris_engine/logic/adapters/api/app.py +272 -0
- ciris_engine/logic/adapters/api/auth.py +159 -0
- ciris_engine/logic/adapters/api/config.py +101 -0
- ciris_engine/logic/adapters/api/constants.py +55 -0
- ciris_engine/logic/adapters/api/dependencies/__init__.py +1 -0
- ciris_engine/logic/adapters/api/dependencies/auth.py +260 -0
- ciris_engine/logic/adapters/api/endpoints/__init__.py +1 -0
- ciris_engine/logic/adapters/api/endpoints/emergency.py +86 -0
- ciris_engine/logic/adapters/api/middleware/__init__.py +1 -0
- ciris_engine/logic/adapters/api/middleware/rate_limiter.py +302 -0
- ciris_engine/logic/adapters/api/models.py +29 -0
- ciris_engine/logic/adapters/api/routes/__init__.py +52 -0
- ciris_engine/logic/adapters/api/routes/agent.py +1762 -0
- ciris_engine/logic/adapters/api/routes/audit.py +707 -0
- ciris_engine/logic/adapters/api/routes/auth.py +1745 -0
- ciris_engine/logic/adapters/api/routes/billing.py +895 -0
- ciris_engine/logic/adapters/api/routes/config.py +329 -0
- ciris_engine/logic/adapters/api/routes/connectors.py +534 -0
- ciris_engine/logic/adapters/api/routes/consent.py +637 -0
- ciris_engine/logic/adapters/api/routes/dsar.py +637 -0
- ciris_engine/logic/adapters/api/routes/dsar_multi_source.py +484 -0
- ciris_engine/logic/adapters/api/routes/emergency.py +302 -0
- ciris_engine/logic/adapters/api/routes/memory.py +733 -0
- ciris_engine/logic/adapters/api/routes/memory_filters.py +230 -0
- ciris_engine/logic/adapters/api/routes/memory_models.py +112 -0
- ciris_engine/logic/adapters/api/routes/memory_queries.py +236 -0
- ciris_engine/logic/adapters/api/routes/memory_query_helpers.py +394 -0
- ciris_engine/logic/adapters/api/routes/memory_visualization.py +359 -0
- ciris_engine/logic/adapters/api/routes/memory_visualization_helpers.py +110 -0
- ciris_engine/logic/adapters/api/routes/partnership.py +541 -0
- ciris_engine/logic/adapters/api/routes/setup.py +1374 -0
- ciris_engine/logic/adapters/api/routes/system.py +3049 -0
- ciris_engine/logic/adapters/api/routes/system_extensions.py +952 -0
- ciris_engine/logic/adapters/api/routes/telemetry.py +1987 -0
- ciris_engine/logic/adapters/api/routes/telemetry_converters.py +141 -0
- ciris_engine/logic/adapters/api/routes/telemetry_helpers.py +111 -0
- ciris_engine/logic/adapters/api/routes/telemetry_logs_reader.py +280 -0
- ciris_engine/logic/adapters/api/routes/telemetry_metrics.py +131 -0
- ciris_engine/logic/adapters/api/routes/telemetry_models.py +190 -0
- ciris_engine/logic/adapters/api/routes/telemetry_otlp.py +878 -0
- ciris_engine/logic/adapters/api/routes/telemetry_resource_helpers.py +191 -0
- ciris_engine/logic/adapters/api/routes/tickets.py +541 -0
- ciris_engine/logic/adapters/api/routes/tools.py +556 -0
- ciris_engine/logic/adapters/api/routes/transparency.py +281 -0
- ciris_engine/logic/adapters/api/routes/users.py +981 -0
- ciris_engine/logic/adapters/api/routes/verification.py +373 -0
- ciris_engine/logic/adapters/api/routes/wa.py +369 -0
- ciris_engine/logic/adapters/api/service_configuration.py +177 -0
- ciris_engine/logic/adapters/api/services/__init__.py +1 -0
- ciris_engine/logic/adapters/api/services/auth_service.py +1417 -0
- ciris_engine/logic/adapters/api/services/oauth_security.py +68 -0
- ciris_engine/logic/adapters/base.py +141 -0
- ciris_engine/logic/adapters/base_adapter.py +73 -0
- ciris_engine/logic/adapters/base_observer.py +1141 -0
- ciris_engine/logic/adapters/base_vision.py +312 -0
- ciris_engine/logic/adapters/cirisnode_client.py +307 -0
- ciris_engine/logic/adapters/cli/__init__.py +3 -0
- ciris_engine/logic/adapters/cli/adapter.py +207 -0
- ciris_engine/logic/adapters/cli/cli_adapter.py +902 -0
- ciris_engine/logic/adapters/cli/cli_observer.py +268 -0
- ciris_engine/logic/adapters/cli/cli_tools.py +427 -0
- ciris_engine/logic/adapters/cli/cli_wa_service.py +134 -0
- ciris_engine/logic/adapters/cli/config.py +73 -0
- ciris_engine/logic/adapters/discord/__init__.py +3 -0
- ciris_engine/logic/adapters/discord/adapter.py +783 -0
- ciris_engine/logic/adapters/discord/ciris_discord_client.py +159 -0
- ciris_engine/logic/adapters/discord/config.py +177 -0
- ciris_engine/logic/adapters/discord/constants.py +185 -0
- ciris_engine/logic/adapters/discord/discord-stubs.pyi +50 -0
- ciris_engine/logic/adapters/discord/discord_adapter.py +1584 -0
- ciris_engine/logic/adapters/discord/discord_audit.py +150 -0
- ciris_engine/logic/adapters/discord/discord_channel_manager.py +351 -0
- ciris_engine/logic/adapters/discord/discord_connection_manager.py +313 -0
- ciris_engine/logic/adapters/discord/discord_embed_formatter.py +369 -0
- ciris_engine/logic/adapters/discord/discord_error_classifier.py +302 -0
- ciris_engine/logic/adapters/discord/discord_error_handler.py +316 -0
- ciris_engine/logic/adapters/discord/discord_guidance_handler.py +460 -0
- ciris_engine/logic/adapters/discord/discord_message_handler.py +207 -0
- ciris_engine/logic/adapters/discord/discord_observer.py +670 -0
- ciris_engine/logic/adapters/discord/discord_rate_limiter.py +249 -0
- ciris_engine/logic/adapters/discord/discord_reaction_handler.py +278 -0
- ciris_engine/logic/adapters/discord/discord_tool_handler.py +465 -0
- ciris_engine/logic/adapters/discord/discord_tool_service.py +790 -0
- ciris_engine/logic/adapters/discord/discord_tools.py +90 -0
- ciris_engine/logic/adapters/discord/discord_vision_helper.py +148 -0
- ciris_engine/logic/adapters/discord/py.typed +0 -0
- ciris_engine/logic/adapters/document_parser.py +320 -0
- ciris_engine/logic/audit/__init__.py +10 -0
- ciris_engine/logic/audit/hash_chain.py +313 -0
- ciris_engine/logic/audit/signature_manager.py +352 -0
- ciris_engine/logic/audit/verifier.py +408 -0
- ciris_engine/logic/buses/__init__.py +21 -0
- ciris_engine/logic/buses/base_bus.py +178 -0
- ciris_engine/logic/buses/bus_manager.py +121 -0
- ciris_engine/logic/buses/communication_bus.py +387 -0
- ciris_engine/logic/buses/llm_bus.py +722 -0
- ciris_engine/logic/buses/memory_bus.py +577 -0
- ciris_engine/logic/buses/prohibitions.py +502 -0
- ciris_engine/logic/buses/runtime_control_bus.py +539 -0
- ciris_engine/logic/buses/tool_bus.py +482 -0
- ciris_engine/logic/buses/wise_bus.py +684 -0
- ciris_engine/logic/config/__init__.py +25 -0
- ciris_engine/logic/config/bootstrap.py +255 -0
- ciris_engine/logic/config/config_accessor.py +202 -0
- ciris_engine/logic/config/db_paths.py +194 -0
- ciris_engine/logic/config/env_utils.py +39 -0
- ciris_engine/logic/conscience/__init__.py +16 -0
- ciris_engine/logic/conscience/build_deferral_package.py +0 -0
- ciris_engine/logic/conscience/core.py +688 -0
- ciris_engine/logic/conscience/interface.py +33 -0
- ciris_engine/logic/conscience/registry.py +76 -0
- ciris_engine/logic/conscience/thought_depth_guardrail.py +231 -0
- ciris_engine/logic/conscience/updated_status_conscience.py +156 -0
- ciris_engine/logic/context/__init__.py +10 -0
- ciris_engine/logic/context/batch_context.py +550 -0
- ciris_engine/logic/context/builder.py +149 -0
- ciris_engine/logic/context/channel_resolution.py +136 -0
- ciris_engine/logic/context/secrets_snapshot.py +52 -0
- ciris_engine/logic/context/system_snapshot.py +116 -0
- ciris_engine/logic/context/system_snapshot_helpers.py +1651 -0
- ciris_engine/logic/covenant/__init__.py +33 -0
- ciris_engine/logic/covenant/executor.py +303 -0
- ciris_engine/logic/covenant/extractor.py +382 -0
- ciris_engine/logic/covenant/handler.py +241 -0
- ciris_engine/logic/covenant/verifier.py +383 -0
- ciris_engine/logic/dma/__init__.py +15 -0
- ciris_engine/logic/dma/action_selection/__init__.py +11 -0
- ciris_engine/logic/dma/action_selection/action_instruction_generator.py +444 -0
- ciris_engine/logic/dma/action_selection/context_builder.py +508 -0
- ciris_engine/logic/dma/action_selection/faculty_integration.py +193 -0
- ciris_engine/logic/dma/action_selection/special_cases.py +132 -0
- ciris_engine/logic/dma/action_selection_pdma.py +365 -0
- ciris_engine/logic/dma/base_dma.py +335 -0
- ciris_engine/logic/dma/csdma.py +239 -0
- ciris_engine/logic/dma/dma_executor.py +575 -0
- ciris_engine/logic/dma/dsdma_base.py +410 -0
- ciris_engine/logic/dma/exceptions.py +4 -0
- ciris_engine/logic/dma/factory.py +150 -0
- ciris_engine/logic/dma/pdma.py +120 -0
- ciris_engine/logic/dma/prompt_loader.py +189 -0
- ciris_engine/logic/dma/prompts/action_selection_pdma.yml +58 -0
- ciris_engine/logic/dma/prompts/csdma_common_sense.yml +28 -0
- ciris_engine/logic/dma/prompts/dsdma_base.yml +17 -0
- ciris_engine/logic/dma/prompts/pdma_ethical.yml +42 -0
- ciris_engine/logic/formatters/__init__.py +26 -0
- ciris_engine/logic/formatters/crisis_resources.py +80 -0
- ciris_engine/logic/formatters/escalation.py +21 -0
- ciris_engine/logic/formatters/identity.py +224 -0
- ciris_engine/logic/formatters/prompt_blocks.py +64 -0
- ciris_engine/logic/formatters/system_snapshot.py +193 -0
- ciris_engine/logic/formatters/user_profiles.py +108 -0
- ciris_engine/logic/handlers/__init__.py +1 -0
- ciris_engine/logic/handlers/control/__init__.py +1 -0
- ciris_engine/logic/handlers/control/defer_handler.py +195 -0
- ciris_engine/logic/handlers/control/ponder_handler.py +154 -0
- ciris_engine/logic/handlers/control/reject_handler.py +81 -0
- ciris_engine/logic/handlers/external/__init__.py +1 -0
- ciris_engine/logic/handlers/external/observe_handler.py +154 -0
- ciris_engine/logic/handlers/external/speak_handler.py +250 -0
- ciris_engine/logic/handlers/external/tool_handler.py +148 -0
- ciris_engine/logic/handlers/memory/__init__.py +1 -0
- ciris_engine/logic/handlers/memory/forget_handler.py +107 -0
- ciris_engine/logic/handlers/memory/memorize_handler.py +391 -0
- ciris_engine/logic/handlers/memory/recall_handler.py +213 -0
- ciris_engine/logic/handlers/terminal/__init__.py +1 -0
- ciris_engine/logic/handlers/terminal/task_complete_handler.py +299 -0
- ciris_engine/logic/infrastructure/__init__.py +1 -0
- ciris_engine/logic/infrastructure/handlers/__init__.py +8 -0
- ciris_engine/logic/infrastructure/handlers/action_dispatcher.py +382 -0
- ciris_engine/logic/infrastructure/handlers/base_handler.py +450 -0
- ciris_engine/logic/infrastructure/handlers/exceptions.py +2 -0
- ciris_engine/logic/infrastructure/handlers/handler_registry.py +59 -0
- ciris_engine/logic/infrastructure/handlers/helpers.py +55 -0
- ciris_engine/logic/infrastructure/step_streaming.py +149 -0
- ciris_engine/logic/infrastructure/sub_services/__init__.py +1 -0
- ciris_engine/logic/infrastructure/sub_services/identity_variance_monitor.py +1035 -0
- ciris_engine/logic/infrastructure/sub_services/pattern_analysis_loop.py +758 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_bootstrap.py +229 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_display.py +176 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_oauth.py +404 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_wizard.py +181 -0
- ciris_engine/logic/persistence/__init__.py +130 -0
- ciris_engine/logic/persistence/analytics.py +97 -0
- ciris_engine/logic/persistence/db/__init__.py +28 -0
- ciris_engine/logic/persistence/db/core.py +520 -0
- ciris_engine/logic/persistence/db/dialect.py +380 -0
- ciris_engine/logic/persistence/db/execution_helpers.py +216 -0
- ciris_engine/logic/persistence/db/migration_runner.py +191 -0
- ciris_engine/logic/persistence/db/operations.py +313 -0
- ciris_engine/logic/persistence/db/query_builder.py +232 -0
- ciris_engine/logic/persistence/db/retry.py +154 -0
- ciris_engine/logic/persistence/db/setup.py +18 -0
- ciris_engine/logic/persistence/migrations/postgres/001_initial_schema.sql +4 -0
- ciris_engine/logic/persistence/migrations/postgres/002_add_retry_status.sql +3 -0
- ciris_engine/logic/persistence/migrations/postgres/003_add_task_update_tracking.sql +8 -0
- ciris_engine/logic/persistence/migrations/postgres/004_add_occurrence_id.sql +54 -0
- ciris_engine/logic/persistence/migrations/postgres/005_add_consolidation_locks.sql +22 -0
- ciris_engine/logic/persistence/migrations/postgres/006_add_correlation_id_unique_index.sql +16 -0
- ciris_engine/logic/persistence/migrations/postgres/007_add_dsar_tickets.sql +39 -0
- ciris_engine/logic/persistence/migrations/postgres/008_rename_to_tickets_add_sop.sql +123 -0
- ciris_engine/logic/persistence/migrations/postgres/009_add_ticket_status_columns.sql +39 -0
- ciris_engine/logic/persistence/migrations/postgres/010_add_images_to_tasks.sql +5 -0
- ciris_engine/logic/persistence/migrations/sqlite/001_initial_schema.sql +357 -0
- ciris_engine/logic/persistence/migrations/sqlite/002_add_retry_status.sql +3 -0
- ciris_engine/logic/persistence/migrations/sqlite/003_add_task_update_tracking.sql +8 -0
- ciris_engine/logic/persistence/migrations/sqlite/004_add_occurrence_id.sql +45 -0
- ciris_engine/logic/persistence/migrations/sqlite/005_add_consolidation_locks.sql +22 -0
- ciris_engine/logic/persistence/migrations/sqlite/006_add_correlation_id_unique_index.sql +16 -0
- ciris_engine/logic/persistence/migrations/sqlite/007_add_dsar_tickets.sql +39 -0
- ciris_engine/logic/persistence/migrations/sqlite/008_rename_to_tickets_add_sop.sql +120 -0
- ciris_engine/logic/persistence/migrations/sqlite/009_add_ticket_status_columns.sql +129 -0
- ciris_engine/logic/persistence/migrations/sqlite/010_add_images_to_tasks.sql +17 -0
- ciris_engine/logic/persistence/models/__init__.py +141 -0
- ciris_engine/logic/persistence/models/correlations.py +881 -0
- ciris_engine/logic/persistence/models/deferral.py +68 -0
- ciris_engine/logic/persistence/models/dsar.py +286 -0
- ciris_engine/logic/persistence/models/graph.py +362 -0
- ciris_engine/logic/persistence/models/identity.py +264 -0
- ciris_engine/logic/persistence/models/queue_status.py +139 -0
- ciris_engine/logic/persistence/models/tasks.py +1043 -0
- ciris_engine/logic/persistence/models/thoughts.py +400 -0
- ciris_engine/logic/persistence/models/tickets.py +518 -0
- ciris_engine/logic/persistence/stores/__init__.py +13 -0
- ciris_engine/logic/persistence/stores/auth_helpers.py +117 -0
- ciris_engine/logic/persistence/stores/authentication_store.py +414 -0
- ciris_engine/logic/persistence/utils.py +212 -0
- ciris_engine/logic/processors/__init__.py +30 -0
- ciris_engine/logic/processors/core/__init__.py +1 -0
- ciris_engine/logic/processors/core/base_processor.py +280 -0
- ciris_engine/logic/processors/core/main_processor.py +1777 -0
- ciris_engine/logic/processors/core/step_decorators.py +1583 -0
- ciris_engine/logic/processors/core/thought_processor/__init__.py +20 -0
- ciris_engine/logic/processors/core/thought_processor/action_execution.py +49 -0
- ciris_engine/logic/processors/core/thought_processor/conscience_execution.py +382 -0
- ciris_engine/logic/processors/core/thought_processor/finalize_action.py +66 -0
- ciris_engine/logic/processors/core/thought_processor/gather_context.py +120 -0
- ciris_engine/logic/processors/core/thought_processor/main.py +920 -0
- ciris_engine/logic/processors/core/thought_processor/perform_aspdma.py +86 -0
- ciris_engine/logic/processors/core/thought_processor/perform_dmas.py +106 -0
- ciris_engine/logic/processors/core/thought_processor/recursive_processing.py +237 -0
- ciris_engine/logic/processors/core/thought_processor/round_complete.py +52 -0
- ciris_engine/logic/processors/core/thought_processor/start_round.py +64 -0
- ciris_engine/logic/processors/exceptions.py +59 -0
- ciris_engine/logic/processors/states/__init__.py +1 -0
- ciris_engine/logic/processors/states/dream_processor.py +1381 -0
- ciris_engine/logic/processors/states/play_processor.py +141 -0
- ciris_engine/logic/processors/states/shutdown_processor.py +623 -0
- ciris_engine/logic/processors/states/solitude_processor.py +305 -0
- ciris_engine/logic/processors/states/wakeup_processor.py +802 -0
- ciris_engine/logic/processors/states/work_processor.py +742 -0
- ciris_engine/logic/processors/support/__init__.py +1 -0
- ciris_engine/logic/processors/support/dma_orchestrator.py +336 -0
- ciris_engine/logic/processors/support/processing_queue.py +133 -0
- ciris_engine/logic/processors/support/shutdown_condition_evaluator.py +294 -0
- ciris_engine/logic/processors/support/state_manager.py +358 -0
- ciris_engine/logic/processors/support/task_manager.py +303 -0
- ciris_engine/logic/processors/support/thought_escalation.py +116 -0
- ciris_engine/logic/processors/support/thought_manager.py +328 -0
- ciris_engine/logic/processors/support/thought_manager_enhanced.py +105 -0
- ciris_engine/logic/registries/__init__.py +34 -0
- ciris_engine/logic/registries/base.py +653 -0
- ciris_engine/logic/registries/circuit_breaker.py +275 -0
- ciris_engine/logic/registries/typed_registries.py +184 -0
- ciris_engine/logic/runtime/__init__.py +7 -0
- ciris_engine/logic/runtime/adapter_loader.py +261 -0
- ciris_engine/logic/runtime/adapter_manager.py +1053 -0
- ciris_engine/logic/runtime/ciris_runtime.py +2342 -0
- ciris_engine/logic/runtime/ciris_runtime_helpers.py +923 -0
- ciris_engine/logic/runtime/component_builder.py +361 -0
- ciris_engine/logic/runtime/identity_manager.py +219 -0
- ciris_engine/logic/runtime/module_loader.py +207 -0
- ciris_engine/logic/runtime/prevent_sideeffects.py +30 -0
- ciris_engine/logic/runtime/runtime_interface.py +23 -0
- ciris_engine/logic/runtime/service_initializer.py +1623 -0
- ciris_engine/logic/secrets/__init__.py +30 -0
- ciris_engine/logic/secrets/encryption.py +175 -0
- ciris_engine/logic/secrets/filter.py +295 -0
- ciris_engine/logic/secrets/service.py +652 -0
- ciris_engine/logic/secrets/store.py +669 -0
- ciris_engine/logic/services/__init__.py +1 -0
- ciris_engine/logic/services/adaptation/__init__.py +3 -0
- ciris_engine/logic/services/base_graph_service.py +142 -0
- ciris_engine/logic/services/base_infrastructure_service.py +69 -0
- ciris_engine/logic/services/base_scheduled_service.py +136 -0
- ciris_engine/logic/services/base_service.py +247 -0
- ciris_engine/logic/services/governance/__init__.py +3 -0
- ciris_engine/logic/services/governance/adaptive_filter/__init__.py +14 -0
- ciris_engine/logic/services/governance/adaptive_filter/service.py +818 -0
- ciris_engine/logic/services/governance/consent/__init__.py +53 -0
- ciris_engine/logic/services/governance/consent/air.py +403 -0
- ciris_engine/logic/services/governance/consent/decay.py +324 -0
- ciris_engine/logic/services/governance/consent/dsar_automation.py +589 -0
- ciris_engine/logic/services/governance/consent/exceptions.py +106 -0
- ciris_engine/logic/services/governance/consent/metrics.py +270 -0
- ciris_engine/logic/services/governance/consent/partnership.py +533 -0
- ciris_engine/logic/services/governance/consent/service.py +1256 -0
- ciris_engine/logic/services/governance/dsar/__init__.py +29 -0
- ciris_engine/logic/services/governance/dsar/orchestrator.py +977 -0
- ciris_engine/logic/services/governance/dsar/schemas.py +141 -0
- ciris_engine/logic/services/governance/dsar/signature_service.py +283 -0
- ciris_engine/logic/services/governance/self_observation/__init__.py +20 -0
- ciris_engine/logic/services/governance/self_observation/service.py +1153 -0
- ciris_engine/logic/services/governance/visibility/__init__.py +17 -0
- ciris_engine/logic/services/governance/visibility/service.py +512 -0
- ciris_engine/logic/services/governance/wise_authority/__init__.py +15 -0
- ciris_engine/logic/services/governance/wise_authority/service.py +827 -0
- ciris_engine/logic/services/graph/__init__.py +5 -0
- ciris_engine/logic/services/graph/audit_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/audit_service/service.py +1675 -0
- ciris_engine/logic/services/graph/base.py +208 -0
- ciris_engine/logic/services/graph/config_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/config_service/service.py +372 -0
- ciris_engine/logic/services/graph/incident_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/incident_service/service.py +803 -0
- ciris_engine/logic/services/graph/memory_service.py +1120 -0
- ciris_engine/logic/services/graph/telemetry_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/telemetry_service/exceptions.py +104 -0
- ciris_engine/logic/services/graph/telemetry_service/helpers.py +1337 -0
- ciris_engine/logic/services/graph/telemetry_service/service.py +2429 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/__init__.py +17 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/aggregation_helpers.py +355 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/cleanup_helpers.py +438 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/compressor.py +260 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/__init__.py +27 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/audit.py +326 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/conversation.py +291 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/memory.py +197 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/metrics.py +251 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/task.py +257 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/trace.py +363 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/data_converter.py +545 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/date_calculation_helpers.py +193 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/db_query_helpers.py +296 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/edge_helpers.py +92 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/edge_manager.py +896 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/extensive_helpers.py +322 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/period_manager.py +152 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/profound_helpers.py +277 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/query_manager.py +812 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/service.py +1692 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/sql_builders.py +363 -0
- ciris_engine/logic/services/infrastructure/__init__.py +1 -0
- ciris_engine/logic/services/infrastructure/authentication/__init__.py +5 -0
- ciris_engine/logic/services/infrastructure/authentication/service.py +1634 -0
- ciris_engine/logic/services/infrastructure/database_maintenance/__init__.py +15 -0
- ciris_engine/logic/services/infrastructure/database_maintenance/service.py +764 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/__init__.py +7 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/ciris_billing_provider.py +755 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/service.py +409 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/simple_credit_provider.py +129 -0
- ciris_engine/logic/services/lifecycle/__init__.py +3 -0
- ciris_engine/logic/services/lifecycle/initialization/__init__.py +10 -0
- ciris_engine/logic/services/lifecycle/initialization/service.py +312 -0
- ciris_engine/logic/services/lifecycle/scheduler/__init__.py +5 -0
- ciris_engine/logic/services/lifecycle/scheduler/service.py +607 -0
- ciris_engine/logic/services/lifecycle/shutdown/__init__.py +9 -0
- ciris_engine/logic/services/lifecycle/shutdown/service.py +378 -0
- ciris_engine/logic/services/lifecycle/time/__init__.py +15 -0
- ciris_engine/logic/services/lifecycle/time/service.py +259 -0
- ciris_engine/logic/services/memory_service/__init__.py +8 -0
- ciris_engine/logic/services/mixins/__init__.py +13 -0
- ciris_engine/logic/services/mixins/example_usage.py +200 -0
- ciris_engine/logic/services/mixins/request_metrics.py +179 -0
- ciris_engine/logic/services/runtime/__init__.py +3 -0
- ciris_engine/logic/services/runtime/adapter_configuration/__init__.py +16 -0
- ciris_engine/logic/services/runtime/adapter_configuration/service.py +674 -0
- ciris_engine/logic/services/runtime/adapter_configuration/session.py +67 -0
- ciris_engine/logic/services/runtime/control_service/__init__.py +5 -0
- ciris_engine/logic/services/runtime/control_service/service.py +2269 -0
- ciris_engine/logic/services/runtime/llm_service/__init__.py +14 -0
- ciris_engine/logic/services/runtime/llm_service/pricing_calculator.py +279 -0
- ciris_engine/logic/services/runtime/llm_service/service.py +930 -0
- ciris_engine/logic/services/tools/__init__.py +5 -0
- ciris_engine/logic/services/tools/core_tool_service/__init__.py +8 -0
- ciris_engine/logic/services/tools/core_tool_service/service.py +852 -0
- ciris_engine/logic/setup/__init__.py +1 -0
- ciris_engine/logic/setup/first_run.py +250 -0
- ciris_engine/logic/setup/wizard.py +327 -0
- ciris_engine/logic/telemetry/__init__.py +46 -0
- ciris_engine/logic/telemetry/core.py +239 -0
- ciris_engine/logic/telemetry/hot_cold_config.py +133 -0
- ciris_engine/logic/telemetry/log_collector.py +190 -0
- ciris_engine/logic/telemetry/resource_monitor.py +7 -0
- ciris_engine/logic/telemetry/security.py +79 -0
- ciris_engine/logic/utils/__init__.py +18 -0
- ciris_engine/logic/utils/channel_utils.py +75 -0
- ciris_engine/logic/utils/consent/__init__.py +1 -0
- ciris_engine/logic/utils/consent/partnership_utils.py +172 -0
- ciris_engine/logic/utils/constants.py +92 -0
- ciris_engine/logic/utils/context_utils.py +145 -0
- ciris_engine/logic/utils/directory_setup.py +533 -0
- ciris_engine/logic/utils/graphql_context_provider.py +152 -0
- ciris_engine/logic/utils/identity_resolution.py +843 -0
- ciris_engine/logic/utils/incident_capture_handler.py +303 -0
- ciris_engine/logic/utils/initialization_manager.py +74 -0
- ciris_engine/logic/utils/jsondict_helpers.py +290 -0
- ciris_engine/logic/utils/log_sanitizer.py +97 -0
- ciris_engine/logic/utils/logging_config.py +151 -0
- ciris_engine/logic/utils/observability_decorators.py +544 -0
- ciris_engine/logic/utils/occurrence_utils.py +155 -0
- ciris_engine/logic/utils/path_resolution.py +281 -0
- ciris_engine/logic/utils/platform_detection.py +286 -0
- ciris_engine/logic/utils/privacy.py +266 -0
- ciris_engine/logic/utils/profile_loader.py +124 -0
- ciris_engine/logic/utils/profile_manager.py +16 -0
- ciris_engine/logic/utils/runtime_utils.py +69 -0
- ciris_engine/logic/utils/shutdown_manager.py +107 -0
- ciris_engine/logic/utils/task_formatters.py +60 -0
- ciris_engine/logic/utils/task_thought_factory.py +404 -0
- ciris_engine/logic/utils/thought_utils.py +54 -0
- ciris_engine/logic/utils/user_utils.py +70 -0
- ciris_engine/protocols/__init__.py +0 -0
- ciris_engine/protocols/adapters/__init__.py +35 -0
- ciris_engine/protocols/adapters/base.py +149 -0
- ciris_engine/protocols/adapters/configurable.py +265 -0
- ciris_engine/protocols/adapters/message.py +90 -0
- ciris_engine/protocols/audit/__init__.py +1 -0
- ciris_engine/protocols/buses/__init__.py +1 -0
- ciris_engine/protocols/config/__init__.py +1 -0
- ciris_engine/protocols/conscience/__init__.py +1 -0
- ciris_engine/protocols/consent.py +88 -0
- ciris_engine/protocols/context/__init__.py +1 -0
- ciris_engine/protocols/data/__init__.py +1 -0
- ciris_engine/protocols/dma/__init__.py +1 -0
- ciris_engine/protocols/dma/base.py +107 -0
- ciris_engine/protocols/faculties.py +34 -0
- ciris_engine/protocols/formatters/__init__.py +1 -0
- ciris_engine/protocols/handlers/__init__.py +1 -0
- ciris_engine/protocols/infrastructure/__init__.py +25 -0
- ciris_engine/protocols/infrastructure/base.py +377 -0
- ciris_engine/protocols/persistence/__init__.py +1 -0
- ciris_engine/protocols/pipeline_control.py +609 -0
- ciris_engine/protocols/processors/__init__.py +19 -0
- ciris_engine/protocols/processors/agent.py +299 -0
- ciris_engine/protocols/processors/base.py +130 -0
- ciris_engine/protocols/processors/orchestration.py +62 -0
- ciris_engine/protocols/registries/__init__.py +1 -0
- ciris_engine/protocols/runtime/__init__.py +1 -0
- ciris_engine/protocols/runtime/base.py +163 -0
- ciris_engine/protocols/secrets/__init__.py +1 -0
- ciris_engine/protocols/services/__init__.py +80 -0
- ciris_engine/protocols/services/adaptation/__init__.py +7 -0
- ciris_engine/protocols/services/adaptation/self_observation.py +265 -0
- ciris_engine/protocols/services/governance/__init__.py +20 -0
- ciris_engine/protocols/services/governance/communication.py +58 -0
- ciris_engine/protocols/services/governance/filter.py +56 -0
- ciris_engine/protocols/services/governance/visibility.py +32 -0
- ciris_engine/protocols/services/governance/wa_auth.py +192 -0
- ciris_engine/protocols/services/governance/wise_authority.py +75 -0
- ciris_engine/protocols/services/graph/__init__.py +19 -0
- ciris_engine/protocols/services/graph/audit.py +92 -0
- ciris_engine/protocols/services/graph/config.py +54 -0
- ciris_engine/protocols/services/graph/incident_management.py +103 -0
- ciris_engine/protocols/services/graph/memory.py +110 -0
- ciris_engine/protocols/services/graph/telemetry.py +51 -0
- ciris_engine/protocols/services/graph/tsdb_consolidation.py +87 -0
- ciris_engine/protocols/services/infrastructure/__init__.py +11 -0
- ciris_engine/protocols/services/infrastructure/authentication.py +159 -0
- ciris_engine/protocols/services/infrastructure/credit_gate.py +46 -0
- ciris_engine/protocols/services/infrastructure/database_maintenance.py +25 -0
- ciris_engine/protocols/services/infrastructure/resource_monitor.py +83 -0
- ciris_engine/protocols/services/lifecycle/__init__.py +13 -0
- ciris_engine/protocols/services/lifecycle/initialization.py +41 -0
- ciris_engine/protocols/services/lifecycle/scheduler.py +42 -0
- ciris_engine/protocols/services/lifecycle/shutdown.py +50 -0
- ciris_engine/protocols/services/lifecycle/time.py +31 -0
- ciris_engine/protocols/services/runtime/__init__.py +13 -0
- ciris_engine/protocols/services/runtime/llm.py +50 -0
- ciris_engine/protocols/services/runtime/runtime_control.py +193 -0
- ciris_engine/protocols/services/runtime/secrets.py +100 -0
- ciris_engine/protocols/services/runtime/tool.py +123 -0
- ciris_engine/protocols/telemetry/__init__.py +1 -0
- ciris_engine/protocols/utils/__init__.py +1 -0
- ciris_engine/schemas/__init__.py +112 -0
- ciris_engine/schemas/actions/__init__.py +37 -0
- ciris_engine/schemas/actions/parameters.py +137 -0
- ciris_engine/schemas/adapters/__init__.py +13 -0
- ciris_engine/schemas/adapters/cirisnode.py +135 -0
- ciris_engine/schemas/adapters/cli.py +97 -0
- ciris_engine/schemas/adapters/cli_tools.py +98 -0
- ciris_engine/schemas/adapters/discord.py +125 -0
- ciris_engine/schemas/adapters/graphql_core.py +144 -0
- ciris_engine/schemas/adapters/registration.py +47 -0
- ciris_engine/schemas/adapters/runtime_context.py +48 -0
- ciris_engine/schemas/adapters/tool_execution.py +45 -0
- ciris_engine/schemas/adapters/tools.py +96 -0
- ciris_engine/schemas/api/__init__.py +1 -0
- ciris_engine/schemas/api/agent.py +50 -0
- ciris_engine/schemas/api/audit.py +38 -0
- ciris_engine/schemas/api/auth.py +351 -0
- ciris_engine/schemas/api/config_security.py +242 -0
- ciris_engine/schemas/api/emergency.py +111 -0
- ciris_engine/schemas/api/responses.py +72 -0
- ciris_engine/schemas/api/runtime.py +26 -0
- ciris_engine/schemas/api/telemetry.py +109 -0
- ciris_engine/schemas/api/wa.py +90 -0
- ciris_engine/schemas/audit/__init__.py +13 -0
- ciris_engine/schemas/audit/core.py +139 -0
- ciris_engine/schemas/audit/hash_chain.py +58 -0
- ciris_engine/schemas/audit/verification.py +131 -0
- ciris_engine/schemas/buses/__init__.py +1 -0
- ciris_engine/schemas/config/__init__.py +41 -0
- ciris_engine/schemas/config/agent.py +279 -0
- ciris_engine/schemas/config/cognitive_state_behaviors.py +194 -0
- ciris_engine/schemas/config/default_dsar_sops.py +178 -0
- ciris_engine/schemas/config/essential.py +195 -0
- ciris_engine/schemas/config/tickets.py +86 -0
- ciris_engine/schemas/conscience/__init__.py +25 -0
- ciris_engine/schemas/conscience/context.py +34 -0
- ciris_engine/schemas/conscience/core.py +145 -0
- ciris_engine/schemas/conscience/results.py +24 -0
- ciris_engine/schemas/consent/__init__.py +5 -0
- ciris_engine/schemas/consent/core.py +404 -0
- ciris_engine/schemas/context/__init__.py +1 -0
- ciris_engine/schemas/covenant.py +382 -0
- ciris_engine/schemas/data/__init__.py +1 -0
- ciris_engine/schemas/dma/__init__.py +16 -0
- ciris_engine/schemas/dma/core.py +199 -0
- ciris_engine/schemas/dma/faculty.py +192 -0
- ciris_engine/schemas/dma/prompts.py +172 -0
- ciris_engine/schemas/dma/results.py +103 -0
- ciris_engine/schemas/formatters/__init__.py +1 -0
- ciris_engine/schemas/handlers/__init__.py +10 -0
- ciris_engine/schemas/handlers/context.py +119 -0
- ciris_engine/schemas/handlers/contexts.py +100 -0
- ciris_engine/schemas/handlers/core.py +167 -0
- ciris_engine/schemas/handlers/memory_schemas.py +67 -0
- ciris_engine/schemas/handlers/schemas.py +95 -0
- ciris_engine/schemas/identity.py +149 -0
- ciris_engine/schemas/infrastructure/__init__.py +1 -0
- ciris_engine/schemas/infrastructure/base.py +256 -0
- ciris_engine/schemas/infrastructure/behavioral_patterns.py +129 -0
- ciris_engine/schemas/infrastructure/feedback_loop.py +57 -0
- ciris_engine/schemas/infrastructure/identity_variance.py +141 -0
- ciris_engine/schemas/infrastructure/oauth.py +175 -0
- ciris_engine/schemas/infrastructure/wa_cli_wizard.py +54 -0
- ciris_engine/schemas/persistence/__init__.py +34 -0
- ciris_engine/schemas/persistence/core.py +140 -0
- ciris_engine/schemas/persistence/correlations.py +73 -0
- ciris_engine/schemas/persistence/postgres/__init__.py +1 -0
- ciris_engine/schemas/persistence/postgres/tables.py +280 -0
- ciris_engine/schemas/persistence/sqlite/__init__.py +1 -0
- ciris_engine/schemas/persistence/sqlite/tables.py +281 -0
- ciris_engine/schemas/platform.py +149 -0
- ciris_engine/schemas/processors/__init__.py +26 -0
- ciris_engine/schemas/processors/base.py +130 -0
- ciris_engine/schemas/processors/cognitive.py +77 -0
- ciris_engine/schemas/processors/context.py +35 -0
- ciris_engine/schemas/processors/core.py +152 -0
- ciris_engine/schemas/processors/dma.py +105 -0
- ciris_engine/schemas/processors/error.py +122 -0
- ciris_engine/schemas/processors/main.py +109 -0
- ciris_engine/schemas/processors/phase_results.py +21 -0
- ciris_engine/schemas/processors/results.py +99 -0
- ciris_engine/schemas/processors/solitude.py +79 -0
- ciris_engine/schemas/processors/state.py +202 -0
- ciris_engine/schemas/processors/state_example.py +177 -0
- ciris_engine/schemas/processors/states.py +21 -0
- ciris_engine/schemas/processors/status.py +34 -0
- ciris_engine/schemas/registries/__init__.py +1 -0
- ciris_engine/schemas/registries/base.py +66 -0
- ciris_engine/schemas/resources/__init__.py +15 -0
- ciris_engine/schemas/resources/crisis.py +315 -0
- ciris_engine/schemas/runtime/__init__.py +42 -0
- ciris_engine/schemas/runtime/adapter_management.py +186 -0
- ciris_engine/schemas/runtime/api.py +58 -0
- ciris_engine/schemas/runtime/audit.py +50 -0
- ciris_engine/schemas/runtime/bootstrap.py +33 -0
- ciris_engine/schemas/runtime/contexts.py +61 -0
- ciris_engine/schemas/runtime/core.py +161 -0
- ciris_engine/schemas/runtime/enums.py +167 -0
- ciris_engine/schemas/runtime/extended.py +232 -0
- ciris_engine/schemas/runtime/manifest.py +311 -0
- ciris_engine/schemas/runtime/memory.py +60 -0
- ciris_engine/schemas/runtime/messages.py +108 -0
- ciris_engine/schemas/runtime/models.py +156 -0
- ciris_engine/schemas/runtime/processing_context.py +43 -0
- ciris_engine/schemas/runtime/protocols_core.py +96 -0
- ciris_engine/schemas/runtime/resources.py +33 -0
- ciris_engine/schemas/runtime/system_context.py +417 -0
- ciris_engine/schemas/secrets/__init__.py +1 -0
- ciris_engine/schemas/secrets/core.py +267 -0
- ciris_engine/schemas/secrets/service.py +95 -0
- ciris_engine/schemas/services/__init__.py +33 -0
- ciris_engine/schemas/services/audit_summary_node.py +172 -0
- ciris_engine/schemas/services/authority/__init__.py +39 -0
- ciris_engine/schemas/services/authority/jwt.py +158 -0
- ciris_engine/schemas/services/authority/wa_updates.py +138 -0
- ciris_engine/schemas/services/authority/wise_authority.py +163 -0
- ciris_engine/schemas/services/authority_core.py +370 -0
- ciris_engine/schemas/services/capabilities.py +72 -0
- ciris_engine/schemas/services/community_core.py +95 -0
- ciris_engine/schemas/services/context.py +111 -0
- ciris_engine/schemas/services/conversation_summary_node.py +189 -0
- ciris_engine/schemas/services/core/__init__.py +153 -0
- ciris_engine/schemas/services/core/runtime.py +262 -0
- ciris_engine/schemas/services/core/runtime_config.py +117 -0
- ciris_engine/schemas/services/core/secrets.py +65 -0
- ciris_engine/schemas/services/correlation_node.py +179 -0
- ciris_engine/schemas/services/credit_gate.py +92 -0
- ciris_engine/schemas/services/discord_nodes.py +299 -0
- ciris_engine/schemas/services/feedback_core.py +131 -0
- ciris_engine/schemas/services/filters_core.py +270 -0
- ciris_engine/schemas/services/governance.py +26 -0
- ciris_engine/schemas/services/graph/__init__.py +26 -0
- ciris_engine/schemas/services/graph/attributes.py +254 -0
- ciris_engine/schemas/services/graph/audit.py +98 -0
- ciris_engine/schemas/services/graph/consolidation.py +338 -0
- ciris_engine/schemas/services/graph/edge_types.py +43 -0
- ciris_engine/schemas/services/graph/edges.py +88 -0
- ciris_engine/schemas/services/graph/incident.py +312 -0
- ciris_engine/schemas/services/graph/memory.py +84 -0
- ciris_engine/schemas/services/graph/node_data.py +174 -0
- ciris_engine/schemas/services/graph/query_results.py +82 -0
- ciris_engine/schemas/services/graph/telemetry.py +250 -0
- ciris_engine/schemas/services/graph/tsdb_consolidation.py +27 -0
- ciris_engine/schemas/services/graph/tsdb_models.py +107 -0
- ciris_engine/schemas/services/graph_core.py +196 -0
- ciris_engine/schemas/services/graph_typed_nodes.py +194 -0
- ciris_engine/schemas/services/infrastructure/__init__.py +1 -0
- ciris_engine/schemas/services/infrastructure/resource_monitor.py +20 -0
- ciris_engine/schemas/services/lifecycle/__init__.py +9 -0
- ciris_engine/schemas/services/lifecycle/initialization.py +33 -0
- ciris_engine/schemas/services/lifecycle/time.py +50 -0
- ciris_engine/schemas/services/llm.py +187 -0
- ciris_engine/schemas/services/metadata.py +43 -0
- ciris_engine/schemas/services/nodes.py +704 -0
- ciris_engine/schemas/services/operations.py +126 -0
- ciris_engine/schemas/services/requests.py +128 -0
- ciris_engine/schemas/services/resources_core.py +182 -0
- ciris_engine/schemas/services/runtime_control.py +1010 -0
- ciris_engine/schemas/services/shutdown.py +88 -0
- ciris_engine/schemas/services/special/__init__.py +0 -0
- ciris_engine/schemas/services/special/self_observation.py +396 -0
- ciris_engine/schemas/services/trace_summary_node.py +199 -0
- ciris_engine/schemas/services/visibility.py +98 -0
- ciris_engine/schemas/streaming/__init__.py +10 -0
- ciris_engine/schemas/streaming/reasoning_stream.py +95 -0
- ciris_engine/schemas/telemetry/__init__.py +0 -0
- ciris_engine/schemas/telemetry/collector.py +67 -0
- ciris_engine/schemas/telemetry/core.py +252 -0
- ciris_engine/schemas/telemetry/unified.py +59 -0
- ciris_engine/schemas/tools.py +72 -0
- ciris_engine/schemas/types.py +47 -0
- ciris_engine/schemas/utils/__init__.py +1 -0
- ciris_engine/schemas/utils/config_validator.py +54 -0
- ciris_engine/utils/__init__.py +1 -0
- ciris_engine/utils/serialization.py +35 -0
- ciris_sdk/__init__.py +124 -0
- ciris_sdk/auth_store.py +261 -0
- ciris_sdk/client.py +261 -0
- ciris_sdk/exceptions.py +73 -0
- ciris_sdk/model_types.py +258 -0
- ciris_sdk/models.py +354 -0
- ciris_sdk/pagination.py +214 -0
- ciris_sdk/rate_limiter.py +188 -0
- ciris_sdk/setup.py +17 -0
- ciris_sdk/telemetry_models.py +257 -0
- ciris_sdk/telemetry_responses.py +199 -0
- ciris_sdk/transport.py +177 -0
- ciris_sdk/websocket.py +400 -0
- main.py +766 -0
|
@@ -0,0 +1,1035 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Identity Variance Monitor Service
|
|
3
|
+
|
|
4
|
+
Tracks drift from baseline identity and triggers WA review if variance exceeds 20% threshold.
|
|
5
|
+
This implements the patent's requirement for bounded identity evolution.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from ciris_engine.logic.buses.memory_bus import MemoryBus
|
|
13
|
+
from ciris_engine.logic.buses.wise_bus import WiseBus
|
|
14
|
+
from ciris_engine.logic.services.base_scheduled_service import BaseScheduledService
|
|
15
|
+
from ciris_engine.logic.utils.jsondict_helpers import get_dict, get_int, get_str
|
|
16
|
+
from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
|
|
17
|
+
from ciris_engine.schemas.infrastructure.behavioral_patterns import BehavioralPattern
|
|
18
|
+
from ciris_engine.schemas.infrastructure.identity_variance import (
|
|
19
|
+
CurrentIdentityData,
|
|
20
|
+
IdentityDiff,
|
|
21
|
+
ServiceStatusMetrics,
|
|
22
|
+
VarianceCheckMetadata,
|
|
23
|
+
VarianceImpact,
|
|
24
|
+
VarianceReport,
|
|
25
|
+
WAReviewRequest,
|
|
26
|
+
)
|
|
27
|
+
from ciris_engine.schemas.runtime.core import AgentIdentityRoot
|
|
28
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
29
|
+
from ciris_engine.schemas.services.graph_core import CONFIG_SCOPE_MAP, ConfigNodeType, GraphNode, GraphScope, NodeType
|
|
30
|
+
from ciris_engine.schemas.services.nodes import IdentitySnapshot
|
|
31
|
+
from ciris_engine.schemas.services.operations import MemoryOpStatus, MemoryQuery
|
|
32
|
+
from ciris_engine.schemas.types import JSONDict
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
# VarianceImpact now imported from schemas
|
|
37
|
+
|
|
38
|
+
# IdentityDiff now imported from schemas
|
|
39
|
+
|
|
40
|
+
# VarianceReport now imported from schemas
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class IdentityVarianceMonitor(BaseScheduledService):
|
|
44
|
+
"""
|
|
45
|
+
Monitors identity drift from baseline and enforces the 20% variance threshold.
|
|
46
|
+
|
|
47
|
+
This service:
|
|
48
|
+
1. Takes periodic snapshots of identity state
|
|
49
|
+
2. Calculates variance from baseline
|
|
50
|
+
3. Triggers WA review if variance > 20%
|
|
51
|
+
4. Provides recommendations for healthy evolution
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
time_service: TimeServiceProtocol,
|
|
57
|
+
memory_bus: Optional[MemoryBus] = None,
|
|
58
|
+
wa_bus: Optional[WiseBus] = None,
|
|
59
|
+
variance_threshold: float = 0.20,
|
|
60
|
+
check_interval_hours: int = 24,
|
|
61
|
+
) -> None:
|
|
62
|
+
# Initialize BaseScheduledService with check interval
|
|
63
|
+
super().__init__(time_service=time_service, run_interval_seconds=check_interval_hours * 3600)
|
|
64
|
+
self._time_service = time_service
|
|
65
|
+
self._memory_bus = memory_bus
|
|
66
|
+
self._wa_bus = wa_bus
|
|
67
|
+
self._variance_threshold = variance_threshold
|
|
68
|
+
self._check_interval_hours = check_interval_hours
|
|
69
|
+
|
|
70
|
+
# Baseline tracking
|
|
71
|
+
self._baseline_snapshot_id: Optional[str] = None
|
|
72
|
+
self._last_check = self._time_service.now() if self._time_service else datetime.now()
|
|
73
|
+
|
|
74
|
+
# Simple variance calculation - no weights needed
|
|
75
|
+
|
|
76
|
+
def set_service_registry(self, registry: Any) -> None:
|
|
77
|
+
"""Set the service registry for accessing buses."""
|
|
78
|
+
self._service_registry = registry
|
|
79
|
+
if not self._memory_bus and registry:
|
|
80
|
+
try:
|
|
81
|
+
from ciris_engine.logic.buses import MemoryBus
|
|
82
|
+
|
|
83
|
+
time_service = self._time_service
|
|
84
|
+
if time_service is not None:
|
|
85
|
+
self._memory_bus = MemoryBus(registry, time_service)
|
|
86
|
+
else:
|
|
87
|
+
logger.error("Time service is None when creating MemoryBus")
|
|
88
|
+
except Exception as e:
|
|
89
|
+
logger.error(f"Failed to initialize memory bus: {e}")
|
|
90
|
+
|
|
91
|
+
if not self._wa_bus and registry:
|
|
92
|
+
try:
|
|
93
|
+
from ciris_engine.logic.buses import WiseBus
|
|
94
|
+
|
|
95
|
+
time_service = self._time_service
|
|
96
|
+
if time_service is not None:
|
|
97
|
+
self._wa_bus = WiseBus(registry, time_service)
|
|
98
|
+
else:
|
|
99
|
+
logger.error("Time service is None when creating WiseBus")
|
|
100
|
+
except Exception as e:
|
|
101
|
+
logger.error(f"Failed to initialize WA bus: {e}")
|
|
102
|
+
|
|
103
|
+
def get_service_type(self) -> ServiceType:
|
|
104
|
+
"""Get service type."""
|
|
105
|
+
return ServiceType.MAINTENANCE # Identity variance monitor is a maintenance sub-service
|
|
106
|
+
|
|
107
|
+
def _get_actions(self) -> List[str]:
|
|
108
|
+
"""Get list of actions this service provides."""
|
|
109
|
+
return [
|
|
110
|
+
"initialize_baseline",
|
|
111
|
+
"check_variance",
|
|
112
|
+
"take_snapshot",
|
|
113
|
+
"calculate_variance",
|
|
114
|
+
"trigger_wa_review",
|
|
115
|
+
"generate_recommendations",
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
def _check_dependencies(self) -> bool:
|
|
119
|
+
"""Check if all dependencies are available."""
|
|
120
|
+
# TimeService is required and provided by base class
|
|
121
|
+
# MemoryBus and WiseBus are optional - we can detect patterns without them
|
|
122
|
+
return True
|
|
123
|
+
|
|
124
|
+
async def initialize_baseline(self, identity: AgentIdentityRoot) -> str:
|
|
125
|
+
"""
|
|
126
|
+
Create the initial baseline snapshot from agent identity.
|
|
127
|
+
|
|
128
|
+
This should be called once during agent initialization.
|
|
129
|
+
"""
|
|
130
|
+
try:
|
|
131
|
+
if not self._memory_bus:
|
|
132
|
+
raise RuntimeError("Memory bus not available")
|
|
133
|
+
|
|
134
|
+
# Create baseline snapshot using IdentitySnapshot type
|
|
135
|
+
if self._time_service is None:
|
|
136
|
+
raise RuntimeError("Time service not available")
|
|
137
|
+
baseline_id = f"identity_baseline_{int(self._time_service.now().timestamp())}"
|
|
138
|
+
|
|
139
|
+
# Create IdentityData from AgentIdentityRoot with proper field mapping
|
|
140
|
+
from ciris_engine.schemas.infrastructure.identity_variance import IdentityData
|
|
141
|
+
|
|
142
|
+
if identity:
|
|
143
|
+
trust_level_value = identity.trust_level if hasattr(identity, "trust_level") else 0.5
|
|
144
|
+
stewardship_value = identity.stewardship if hasattr(identity, "stewardship") else None
|
|
145
|
+
identity_data = IdentityData(
|
|
146
|
+
agent_id=identity.agent_id,
|
|
147
|
+
description=identity.core_profile.description,
|
|
148
|
+
role=identity.core_profile.role_description,
|
|
149
|
+
trust_level=trust_level_value,
|
|
150
|
+
stewardship=stewardship_value,
|
|
151
|
+
)
|
|
152
|
+
else:
|
|
153
|
+
identity_data = None
|
|
154
|
+
|
|
155
|
+
baseline_snapshot = IdentitySnapshot(
|
|
156
|
+
id=baseline_id,
|
|
157
|
+
scope=GraphScope.IDENTITY,
|
|
158
|
+
system_state={"type": "BASELINE"},
|
|
159
|
+
expires_at=None,
|
|
160
|
+
identity_root=identity_data,
|
|
161
|
+
snapshot_id=baseline_id,
|
|
162
|
+
timestamp=self._time_service.now() if self._time_service else datetime.now(),
|
|
163
|
+
agent_id=identity.agent_id,
|
|
164
|
+
identity_hash=identity.identity_hash,
|
|
165
|
+
core_purpose=identity.core_profile.description,
|
|
166
|
+
role=identity.core_profile.role_description,
|
|
167
|
+
permitted_actions=identity.permitted_actions,
|
|
168
|
+
restricted_capabilities=identity.restricted_capabilities,
|
|
169
|
+
ethical_boundaries=self._extract_ethical_boundaries(identity),
|
|
170
|
+
trust_parameters=self._extract_trust_parameters(identity),
|
|
171
|
+
personality_traits=identity.core_profile.areas_of_expertise, # Use areas of expertise as personality traits
|
|
172
|
+
communication_style=identity.core_profile.startup_instructions or "standard",
|
|
173
|
+
learning_enabled=True, # Default to enabled
|
|
174
|
+
adaptation_rate=0.1, # Conservative adaptation rate
|
|
175
|
+
is_baseline=True, # Mark as baseline snapshot
|
|
176
|
+
reason="Initial baseline establishment",
|
|
177
|
+
created_by="identity_variance_monitor",
|
|
178
|
+
updated_by="identity_variance_monitor",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
baseline_node = baseline_snapshot.to_graph_node()
|
|
182
|
+
|
|
183
|
+
# Store baseline
|
|
184
|
+
if self._memory_bus:
|
|
185
|
+
result = await self._memory_bus.memorize(
|
|
186
|
+
node=baseline_node,
|
|
187
|
+
handler_name="identity_variance_monitor",
|
|
188
|
+
metadata=VarianceCheckMetadata(
|
|
189
|
+
handler_name="identity_variance_monitor",
|
|
190
|
+
check_reason="baseline",
|
|
191
|
+
previous_check=None,
|
|
192
|
+
check_type="baseline",
|
|
193
|
+
baseline_established=self._time_service.now() if self._time_service else datetime.now(),
|
|
194
|
+
).model_dump(),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if result.status == MemoryOpStatus.OK:
|
|
198
|
+
self._baseline_snapshot_id = baseline_id
|
|
199
|
+
logger.info(f"Identity baseline established: {baseline_id}")
|
|
200
|
+
|
|
201
|
+
# Also store baseline reference
|
|
202
|
+
reference_node = GraphNode(
|
|
203
|
+
id="identity_baseline_current",
|
|
204
|
+
type=NodeType.CONCEPT,
|
|
205
|
+
scope=GraphScope.IDENTITY,
|
|
206
|
+
attributes={
|
|
207
|
+
"baseline_id": baseline_id,
|
|
208
|
+
"established_at": (
|
|
209
|
+
self._time_service.now().isoformat() if self._time_service else datetime.now().isoformat()
|
|
210
|
+
),
|
|
211
|
+
},
|
|
212
|
+
updated_by="identity_variance_monitor",
|
|
213
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
214
|
+
)
|
|
215
|
+
if self._memory_bus:
|
|
216
|
+
await self._memory_bus.memorize(reference_node, handler_name="identity_variance_monitor")
|
|
217
|
+
|
|
218
|
+
return baseline_id
|
|
219
|
+
else:
|
|
220
|
+
raise RuntimeError(f"Failed to store baseline: {result.error}")
|
|
221
|
+
|
|
222
|
+
except Exception as e:
|
|
223
|
+
logger.error(f"Failed to initialize baseline: {e}")
|
|
224
|
+
raise
|
|
225
|
+
|
|
226
|
+
async def rebaseline_with_approval(self, wa_approval_token: str) -> str:
|
|
227
|
+
"""
|
|
228
|
+
Re-baseline identity with WA approval.
|
|
229
|
+
|
|
230
|
+
This allows the agent to accept current state as the new baseline,
|
|
231
|
+
resetting variance to 0% and allowing another 20% of evolution.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
wa_approval_token: Proof of WA approval for re-baselining
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
New baseline snapshot ID
|
|
238
|
+
"""
|
|
239
|
+
try:
|
|
240
|
+
# Verify WA approval
|
|
241
|
+
if not wa_approval_token:
|
|
242
|
+
raise ValueError("WA approval token required for re-baselining")
|
|
243
|
+
|
|
244
|
+
# Log the re-baseline event
|
|
245
|
+
logger.info(f"Re-baselining identity with WA approval: {wa_approval_token}")
|
|
246
|
+
|
|
247
|
+
# Take current snapshot as new baseline
|
|
248
|
+
# Get current identity data
|
|
249
|
+
identity_nodes = await self._gather_identity_nodes()
|
|
250
|
+
config_nodes = await self._gather_config_nodes()
|
|
251
|
+
behavioral_patterns = await self._analyze_behavioral_patterns()
|
|
252
|
+
|
|
253
|
+
current_identity = await self._extract_current_identity(identity_nodes)
|
|
254
|
+
trust_params = self._extract_current_trust_parameters(config_nodes)
|
|
255
|
+
|
|
256
|
+
# Convert behavioral patterns to dict format
|
|
257
|
+
behavioral_patterns_dict = {}
|
|
258
|
+
for pattern in behavioral_patterns:
|
|
259
|
+
behavioral_patterns_dict[pattern.pattern_type] = pattern.frequency
|
|
260
|
+
|
|
261
|
+
# Create new baseline snapshot
|
|
262
|
+
if self._time_service is None:
|
|
263
|
+
raise RuntimeError("Time service not available")
|
|
264
|
+
baseline_id = f"identity_baseline_{int(self._time_service.now().timestamp())}"
|
|
265
|
+
baseline_snapshot = IdentitySnapshot(
|
|
266
|
+
id=baseline_id,
|
|
267
|
+
scope=GraphScope.IDENTITY,
|
|
268
|
+
system_state={"type": "BASELINE"},
|
|
269
|
+
expires_at=None,
|
|
270
|
+
identity_root=None, # No identity root for re-baseline
|
|
271
|
+
snapshot_id=baseline_id,
|
|
272
|
+
timestamp=self._time_service.now() if self._time_service else datetime.now(),
|
|
273
|
+
agent_id=current_identity.agent_id,
|
|
274
|
+
identity_hash=current_identity.identity_hash,
|
|
275
|
+
core_purpose=current_identity.core_purpose,
|
|
276
|
+
role=current_identity.role,
|
|
277
|
+
permitted_actions=current_identity.permitted_actions,
|
|
278
|
+
restricted_capabilities=current_identity.restricted_capabilities,
|
|
279
|
+
ethical_boundaries=current_identity.ethical_boundaries,
|
|
280
|
+
trust_parameters=trust_params,
|
|
281
|
+
personality_traits=current_identity.personality_traits,
|
|
282
|
+
communication_style=current_identity.communication_style,
|
|
283
|
+
learning_enabled=current_identity.learning_enabled,
|
|
284
|
+
adaptation_rate=current_identity.adaptation_rate,
|
|
285
|
+
is_baseline=True, # Mark as baseline
|
|
286
|
+
behavioral_patterns=behavioral_patterns_dict,
|
|
287
|
+
reason=f"Re-baselined with WA approval: {wa_approval_token}",
|
|
288
|
+
created_by="identity_variance_monitor",
|
|
289
|
+
updated_by="identity_variance_monitor",
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
if not self._memory_bus:
|
|
293
|
+
raise RuntimeError("Memory bus not available")
|
|
294
|
+
|
|
295
|
+
result = await self._memory_bus.memorize(
|
|
296
|
+
node=baseline_snapshot.to_graph_node(),
|
|
297
|
+
handler_name="identity_variance_monitor",
|
|
298
|
+
metadata=VarianceCheckMetadata(
|
|
299
|
+
handler_name="identity_variance_monitor",
|
|
300
|
+
check_reason="rebaseline",
|
|
301
|
+
previous_check=self._last_check,
|
|
302
|
+
check_type="rebaseline",
|
|
303
|
+
baseline_established=self._time_service.now(),
|
|
304
|
+
).model_dump(),
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
if result.status == MemoryOpStatus.OK:
|
|
308
|
+
# Update baseline reference
|
|
309
|
+
old_baseline = self._baseline_snapshot_id
|
|
310
|
+
self._baseline_snapshot_id = baseline_id
|
|
311
|
+
|
|
312
|
+
# NOTE: Baseline correlation is tracked through audit trail
|
|
313
|
+
# via the identity_baseline snapshot stored in memory_bus above.
|
|
314
|
+
# No additional correlation service needed - audit service provides
|
|
315
|
+
# full history tracking through the audit event system.
|
|
316
|
+
|
|
317
|
+
logger.info(f"Successfully re-baselined identity to {baseline_id} (previous: {old_baseline})")
|
|
318
|
+
return baseline_id
|
|
319
|
+
else:
|
|
320
|
+
raise RuntimeError(f"Failed to store new baseline: {result.error}")
|
|
321
|
+
|
|
322
|
+
except Exception as e:
|
|
323
|
+
logger.error(f"Failed to re-baseline: {e}")
|
|
324
|
+
raise
|
|
325
|
+
|
|
326
|
+
async def check_variance(self, force: bool = False) -> VarianceReport:
|
|
327
|
+
"""
|
|
328
|
+
Check current identity variance from baseline.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
force: Force check even if not due
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
VarianceReport with analysis results
|
|
335
|
+
"""
|
|
336
|
+
try:
|
|
337
|
+
# Check if due for variance check
|
|
338
|
+
if self._time_service is None:
|
|
339
|
+
return VarianceReport(
|
|
340
|
+
timestamp=datetime.now(),
|
|
341
|
+
baseline_snapshot_id=self._baseline_snapshot_id or "unknown",
|
|
342
|
+
current_snapshot_id="unavailable",
|
|
343
|
+
total_variance=0.0,
|
|
344
|
+
differences=[],
|
|
345
|
+
requires_wa_review=False,
|
|
346
|
+
recommendations=["Time service unavailable"],
|
|
347
|
+
)
|
|
348
|
+
time_since_last = self._time_service.now() - self._last_check
|
|
349
|
+
if not force and time_since_last.total_seconds() < self._check_interval_hours * 3600:
|
|
350
|
+
logger.debug("Variance check not due yet")
|
|
351
|
+
|
|
352
|
+
if not self._baseline_snapshot_id:
|
|
353
|
+
# Try to load baseline
|
|
354
|
+
await self._load_baseline()
|
|
355
|
+
if not self._baseline_snapshot_id:
|
|
356
|
+
raise RuntimeError("No baseline snapshot available")
|
|
357
|
+
|
|
358
|
+
# Take current snapshot
|
|
359
|
+
current_snapshot = await self._take_identity_snapshot()
|
|
360
|
+
|
|
361
|
+
# Load baseline snapshot
|
|
362
|
+
baseline_snapshot = await self._load_snapshot(self._baseline_snapshot_id)
|
|
363
|
+
|
|
364
|
+
# Calculate simple variance percentage
|
|
365
|
+
total_variance = self._calculate_variance(baseline_snapshot, current_snapshot)
|
|
366
|
+
|
|
367
|
+
# Create report
|
|
368
|
+
report = VarianceReport(
|
|
369
|
+
timestamp=self._time_service.now() if self._time_service else datetime.now(),
|
|
370
|
+
baseline_snapshot_id=self._baseline_snapshot_id,
|
|
371
|
+
current_snapshot_id=current_snapshot.id,
|
|
372
|
+
total_variance=total_variance,
|
|
373
|
+
differences=[], # Simplified - just track variance percentage
|
|
374
|
+
requires_wa_review=total_variance > self._variance_threshold,
|
|
375
|
+
recommendations=self._generate_simple_recommendations(total_variance),
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
# Store report
|
|
379
|
+
await self._store_variance_report(report)
|
|
380
|
+
|
|
381
|
+
# Trigger WA review if needed
|
|
382
|
+
if report.requires_wa_review:
|
|
383
|
+
await self._trigger_wa_review(report)
|
|
384
|
+
|
|
385
|
+
if self._time_service:
|
|
386
|
+
self._last_check = self._time_service.now()
|
|
387
|
+
|
|
388
|
+
return report
|
|
389
|
+
|
|
390
|
+
except Exception as e:
|
|
391
|
+
logger.error(f"Failed to check variance: {e}")
|
|
392
|
+
raise
|
|
393
|
+
|
|
394
|
+
async def _take_identity_snapshot(self) -> GraphNode:
|
|
395
|
+
"""Take a snapshot of current identity state."""
|
|
396
|
+
if self._time_service is None:
|
|
397
|
+
raise RuntimeError("Time service not available")
|
|
398
|
+
snapshot_id = f"identity_snapshot_{int(self._time_service.now().timestamp())}"
|
|
399
|
+
|
|
400
|
+
# Gather current identity components
|
|
401
|
+
identity_nodes = await self._gather_identity_nodes()
|
|
402
|
+
config_nodes = await self._gather_config_nodes()
|
|
403
|
+
behavioral_patterns = await self._analyze_behavioral_patterns()
|
|
404
|
+
|
|
405
|
+
# Extract current identity data from nodes
|
|
406
|
+
current_identity = await self._extract_current_identity(identity_nodes)
|
|
407
|
+
trust_params = self._extract_current_trust_parameters(config_nodes)
|
|
408
|
+
capability_changes = self._extract_capability_changes(identity_nodes)
|
|
409
|
+
|
|
410
|
+
# Convert behavioral patterns to dict format for storage
|
|
411
|
+
behavioral_patterns_dict = {}
|
|
412
|
+
for pattern in behavioral_patterns:
|
|
413
|
+
behavioral_patterns_dict[pattern.pattern_type] = pattern.frequency
|
|
414
|
+
|
|
415
|
+
# Create snapshot using IdentitySnapshot type
|
|
416
|
+
snapshot = IdentitySnapshot(
|
|
417
|
+
id=snapshot_id,
|
|
418
|
+
scope=GraphScope.IDENTITY,
|
|
419
|
+
system_state={"type": "SNAPSHOT"},
|
|
420
|
+
expires_at=None,
|
|
421
|
+
identity_root=None, # No identity root for snapshots
|
|
422
|
+
snapshot_id=snapshot_id,
|
|
423
|
+
timestamp=self._time_service.now(),
|
|
424
|
+
agent_id=current_identity.agent_id,
|
|
425
|
+
identity_hash=current_identity.identity_hash,
|
|
426
|
+
core_purpose=current_identity.core_purpose,
|
|
427
|
+
role=current_identity.role,
|
|
428
|
+
permitted_actions=current_identity.permitted_actions,
|
|
429
|
+
restricted_capabilities=current_identity.restricted_capabilities,
|
|
430
|
+
ethical_boundaries=current_identity.ethical_boundaries,
|
|
431
|
+
trust_parameters=trust_params,
|
|
432
|
+
personality_traits=current_identity.personality_traits,
|
|
433
|
+
communication_style=current_identity.communication_style,
|
|
434
|
+
learning_enabled=current_identity.learning_enabled,
|
|
435
|
+
adaptation_rate=current_identity.adaptation_rate,
|
|
436
|
+
is_baseline=False, # This is a regular snapshot, not baseline
|
|
437
|
+
behavioral_patterns=behavioral_patterns_dict,
|
|
438
|
+
reason="Periodic variance check",
|
|
439
|
+
attributes={
|
|
440
|
+
"identity_nodes": len(identity_nodes),
|
|
441
|
+
"config_nodes": len(config_nodes),
|
|
442
|
+
"capability_changes": capability_changes,
|
|
443
|
+
},
|
|
444
|
+
created_by="identity_variance_monitor",
|
|
445
|
+
updated_by="identity_variance_monitor",
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
# Store snapshot
|
|
449
|
+
if self._memory_bus:
|
|
450
|
+
await self._memory_bus.memorize(
|
|
451
|
+
node=snapshot.to_graph_node(),
|
|
452
|
+
handler_name="identity_variance_monitor",
|
|
453
|
+
metadata=VarianceCheckMetadata(
|
|
454
|
+
handler_name="identity_variance_monitor",
|
|
455
|
+
check_reason="snapshot",
|
|
456
|
+
previous_check=self._last_check,
|
|
457
|
+
check_type="snapshot",
|
|
458
|
+
baseline_established=self._last_check,
|
|
459
|
+
).model_dump(),
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
return snapshot.to_graph_node()
|
|
463
|
+
|
|
464
|
+
def _calculate_differences(self, baseline: GraphNode, current: GraphNode) -> List[IdentityDiff]:
|
|
465
|
+
"""Calculate differences between baseline and current snapshots."""
|
|
466
|
+
differences = []
|
|
467
|
+
|
|
468
|
+
# Compare ethical boundaries
|
|
469
|
+
baseline_ethics = (
|
|
470
|
+
getattr(baseline.attributes, "ethical_boundaries", {})
|
|
471
|
+
if hasattr(baseline.attributes, "ethical_boundaries")
|
|
472
|
+
else {}
|
|
473
|
+
)
|
|
474
|
+
current_ethics = (
|
|
475
|
+
getattr(current.attributes, "ethical_boundaries", {})
|
|
476
|
+
if hasattr(current.attributes, "ethical_boundaries")
|
|
477
|
+
else {}
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
for key in set(baseline_ethics.keys()) | set(current_ethics.keys()):
|
|
481
|
+
if key not in current_ethics:
|
|
482
|
+
differences.append(
|
|
483
|
+
IdentityDiff(
|
|
484
|
+
node_id=f"ethics_{key}",
|
|
485
|
+
diff_type="removed",
|
|
486
|
+
impact=VarianceImpact.CRITICAL,
|
|
487
|
+
baseline_value=str(baseline_ethics[key]),
|
|
488
|
+
current_value=None,
|
|
489
|
+
description=f"Ethical boundary '{key}' removed",
|
|
490
|
+
)
|
|
491
|
+
)
|
|
492
|
+
elif key not in baseline_ethics:
|
|
493
|
+
differences.append(
|
|
494
|
+
IdentityDiff(
|
|
495
|
+
node_id=f"ethics_{key}",
|
|
496
|
+
diff_type="added",
|
|
497
|
+
impact=VarianceImpact.CRITICAL,
|
|
498
|
+
baseline_value=None,
|
|
499
|
+
current_value=str(current_ethics[key]),
|
|
500
|
+
description=f"Ethical boundary '{key}' added",
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
elif baseline_ethics[key] != current_ethics[key]:
|
|
504
|
+
differences.append(
|
|
505
|
+
IdentityDiff(
|
|
506
|
+
node_id=f"ethics_{key}",
|
|
507
|
+
diff_type="modified",
|
|
508
|
+
impact=VarianceImpact.CRITICAL,
|
|
509
|
+
baseline_value=str(baseline_ethics[key]),
|
|
510
|
+
current_value=str(current_ethics[key]),
|
|
511
|
+
description=f"Ethical boundary '{key}' modified",
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
# Compare capabilities
|
|
516
|
+
baseline_caps = set(
|
|
517
|
+
getattr(baseline.attributes, "capability_changes", [])
|
|
518
|
+
if hasattr(baseline.attributes, "capability_changes")
|
|
519
|
+
else []
|
|
520
|
+
)
|
|
521
|
+
current_caps = set(
|
|
522
|
+
getattr(current.attributes, "capability_changes", [])
|
|
523
|
+
if hasattr(current.attributes, "capability_changes")
|
|
524
|
+
else []
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
for cap in baseline_caps - current_caps:
|
|
528
|
+
differences.append(
|
|
529
|
+
IdentityDiff(
|
|
530
|
+
node_id=f"capability_{cap}",
|
|
531
|
+
diff_type="removed",
|
|
532
|
+
impact=VarianceImpact.HIGH,
|
|
533
|
+
baseline_value=str(cap),
|
|
534
|
+
current_value=None,
|
|
535
|
+
description=f"Capability '{cap}' removed",
|
|
536
|
+
)
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
for cap in current_caps - baseline_caps:
|
|
540
|
+
differences.append(
|
|
541
|
+
IdentityDiff(
|
|
542
|
+
node_id=f"capability_{cap}",
|
|
543
|
+
diff_type="added",
|
|
544
|
+
impact=VarianceImpact.HIGH,
|
|
545
|
+
baseline_value=None,
|
|
546
|
+
current_value=str(cap),
|
|
547
|
+
description=f"Capability '{cap}' added",
|
|
548
|
+
)
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
# Compare behavioral patterns
|
|
552
|
+
baseline_patterns = (
|
|
553
|
+
getattr(baseline.attributes, "behavioral_patterns", {})
|
|
554
|
+
if hasattr(baseline.attributes, "behavioral_patterns")
|
|
555
|
+
else {}
|
|
556
|
+
)
|
|
557
|
+
current_patterns = (
|
|
558
|
+
getattr(current.attributes, "behavioral_patterns", {})
|
|
559
|
+
if hasattr(current.attributes, "behavioral_patterns")
|
|
560
|
+
else {}
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
pattern_diff = self._compare_patterns(baseline_patterns, current_patterns)
|
|
564
|
+
differences.extend(pattern_diff)
|
|
565
|
+
|
|
566
|
+
return differences
|
|
567
|
+
|
|
568
|
+
def _calculate_variance(self, baseline_snapshot: GraphNode, current_snapshot: GraphNode) -> float:
|
|
569
|
+
"""
|
|
570
|
+
Calculate simple percentage variance between snapshots.
|
|
571
|
+
|
|
572
|
+
Returns:
|
|
573
|
+
Variance as a percentage (0.0 to 1.0)
|
|
574
|
+
"""
|
|
575
|
+
# Get all attributes from both snapshots
|
|
576
|
+
baseline_attrs = (
|
|
577
|
+
baseline_snapshot.attributes
|
|
578
|
+
if isinstance(baseline_snapshot.attributes, dict)
|
|
579
|
+
else (
|
|
580
|
+
baseline_snapshot.attributes.model_dump() if hasattr(baseline_snapshot.attributes, "model_dump") else {}
|
|
581
|
+
)
|
|
582
|
+
)
|
|
583
|
+
current_attrs = (
|
|
584
|
+
current_snapshot.attributes
|
|
585
|
+
if isinstance(current_snapshot.attributes, dict)
|
|
586
|
+
else current_snapshot.attributes.model_dump() if hasattr(current_snapshot.attributes, "model_dump") else {}
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
# Get all unique keys from both snapshots
|
|
590
|
+
all_keys = set(baseline_attrs.keys()) | set(current_attrs.keys())
|
|
591
|
+
|
|
592
|
+
# Skip metadata keys that don't represent identity
|
|
593
|
+
skip_keys = {"created_at", "updated_at", "timestamp", "snapshot_type"}
|
|
594
|
+
identity_keys = [k for k in all_keys if k not in skip_keys]
|
|
595
|
+
|
|
596
|
+
if not identity_keys:
|
|
597
|
+
return 0.0
|
|
598
|
+
|
|
599
|
+
# Count differences
|
|
600
|
+
differences = 0
|
|
601
|
+
for key in identity_keys:
|
|
602
|
+
baseline_value = baseline_attrs.get(key)
|
|
603
|
+
current_value = current_attrs.get(key)
|
|
604
|
+
|
|
605
|
+
# Simple equality check
|
|
606
|
+
if baseline_value != current_value:
|
|
607
|
+
differences += 1
|
|
608
|
+
|
|
609
|
+
# Simple percentage calculation
|
|
610
|
+
variance = differences / len(identity_keys)
|
|
611
|
+
return variance
|
|
612
|
+
|
|
613
|
+
def _generate_simple_recommendations(self, total_variance: float) -> List[str]:
|
|
614
|
+
"""Generate simple recommendations based on variance percentage."""
|
|
615
|
+
recommendations = []
|
|
616
|
+
|
|
617
|
+
if total_variance > self._variance_threshold:
|
|
618
|
+
recommendations.append(
|
|
619
|
+
f"CRITICAL: Identity variance ({total_variance:.1%}) exceeds 20% threshold. "
|
|
620
|
+
"WA review required. Consider re-baselining with WA approval."
|
|
621
|
+
)
|
|
622
|
+
elif total_variance > self._variance_threshold * 0.8:
|
|
623
|
+
recommendations.append(
|
|
624
|
+
f"WARNING: Identity variance ({total_variance:.1%}) approaching 20% threshold. "
|
|
625
|
+
"Be mindful of additional changes."
|
|
626
|
+
)
|
|
627
|
+
elif total_variance < self._variance_threshold * 0.5:
|
|
628
|
+
recommendations.append(
|
|
629
|
+
f"Healthy: Identity variance ({total_variance:.1%}) is well within safe bounds. "
|
|
630
|
+
"Room for continued growth and adaptation."
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
return recommendations
|
|
634
|
+
|
|
635
|
+
async def _trigger_wa_review(self, report: VarianceReport) -> None:
|
|
636
|
+
"""Trigger Wise Authority review for excessive variance."""
|
|
637
|
+
try:
|
|
638
|
+
if not self._wa_bus:
|
|
639
|
+
logger.error("WA bus not available for variance review")
|
|
640
|
+
return
|
|
641
|
+
|
|
642
|
+
# Create review request
|
|
643
|
+
review_request = WAReviewRequest(
|
|
644
|
+
request_id=f"variance_review_{int(self._time_service.now().timestamp() if self._time_service else datetime.now().timestamp())}",
|
|
645
|
+
timestamp=self._time_service.now() if self._time_service else datetime.now(),
|
|
646
|
+
current_variance=report.total_variance,
|
|
647
|
+
variance_report=report,
|
|
648
|
+
critical_changes=[d for d in report.differences if d.impact == VarianceImpact.CRITICAL],
|
|
649
|
+
proposed_actions=report.recommendations,
|
|
650
|
+
urgency="high" if report.total_variance > 0.30 else "moderate",
|
|
651
|
+
)
|
|
652
|
+
|
|
653
|
+
# Send to WA
|
|
654
|
+
await self._wa_bus.request_review(
|
|
655
|
+
review_type="identity_variance",
|
|
656
|
+
review_data=review_request.model_dump(),
|
|
657
|
+
handler_name="identity_variance_monitor",
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
logger.warning(f"WA review triggered for identity variance {report.total_variance:.1%}")
|
|
661
|
+
|
|
662
|
+
except Exception as e:
|
|
663
|
+
logger.error(f"Failed to trigger WA review: {e}")
|
|
664
|
+
|
|
665
|
+
async def _gather_identity_nodes(self) -> List[GraphNode]:
|
|
666
|
+
"""Gather all identity-scoped nodes."""
|
|
667
|
+
try:
|
|
668
|
+
# Query identity nodes
|
|
669
|
+
query = MemoryQuery(node_id="*", scope=GraphScope.IDENTITY, type=None, include_edges=False, depth=1)
|
|
670
|
+
|
|
671
|
+
if self._memory_bus:
|
|
672
|
+
nodes = await self._memory_bus.recall(recall_query=query, handler_name="identity_variance_monitor")
|
|
673
|
+
return nodes
|
|
674
|
+
return []
|
|
675
|
+
|
|
676
|
+
except Exception:
|
|
677
|
+
return []
|
|
678
|
+
|
|
679
|
+
async def _gather_config_nodes(self) -> List[GraphNode]:
|
|
680
|
+
"""Gather all configuration nodes."""
|
|
681
|
+
config_nodes: List[GraphNode] = []
|
|
682
|
+
|
|
683
|
+
# Query each config type
|
|
684
|
+
for config_type in ConfigNodeType:
|
|
685
|
+
try:
|
|
686
|
+
scope = CONFIG_SCOPE_MAP[config_type]
|
|
687
|
+
query = MemoryQuery(
|
|
688
|
+
node_id=f"config/{config_type.value}/*", scope=scope, type=None, include_edges=False, depth=1
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
if self._memory_bus:
|
|
692
|
+
nodes = await self._memory_bus.recall(recall_query=query, handler_name="identity_variance_monitor")
|
|
693
|
+
config_nodes.extend(nodes)
|
|
694
|
+
|
|
695
|
+
except Exception:
|
|
696
|
+
continue
|
|
697
|
+
|
|
698
|
+
return config_nodes
|
|
699
|
+
|
|
700
|
+
async def _analyze_behavioral_patterns(self) -> List[BehavioralPattern]:
|
|
701
|
+
"""Analyze recent behavioral patterns from audit trail."""
|
|
702
|
+
from ciris_engine.schemas.infrastructure.behavioral_patterns import BehavioralPattern
|
|
703
|
+
|
|
704
|
+
patterns: List[BehavioralPattern] = []
|
|
705
|
+
try:
|
|
706
|
+
# Query recent actions
|
|
707
|
+
if not self._memory_bus:
|
|
708
|
+
return patterns
|
|
709
|
+
recent_actions = await self._memory_bus.recall_timeseries(
|
|
710
|
+
scope="local",
|
|
711
|
+
hours=24 * 7, # Last week
|
|
712
|
+
correlation_types=["AUDIT_EVENT"],
|
|
713
|
+
handler_name="identity_variance_monitor",
|
|
714
|
+
)
|
|
715
|
+
|
|
716
|
+
# Analyze patterns
|
|
717
|
+
action_counts: Dict[str, int] = {}
|
|
718
|
+
first_seen: Dict[str, datetime] = {}
|
|
719
|
+
last_seen: Dict[str, datetime] = {}
|
|
720
|
+
evidence: Dict[str, List[str]] = {}
|
|
721
|
+
|
|
722
|
+
for action in recent_actions:
|
|
723
|
+
# TimeSeriesDataPoint has tags which may contain action_type
|
|
724
|
+
action_type = action.tags.get("action_type", "unknown") if action.tags else "unknown"
|
|
725
|
+
action_counts[action_type] = action_counts.get(action_type, 0) + 1
|
|
726
|
+
|
|
727
|
+
# Track first/last seen
|
|
728
|
+
action_time = action.timestamp
|
|
729
|
+
if action_type not in first_seen:
|
|
730
|
+
first_seen[action_type] = action_time
|
|
731
|
+
last_seen[action_type] = action_time
|
|
732
|
+
|
|
733
|
+
# Collect evidence (limit to 5 examples)
|
|
734
|
+
if action_type not in evidence:
|
|
735
|
+
evidence[action_type] = []
|
|
736
|
+
if len(evidence[action_type]) < 5:
|
|
737
|
+
evidence[action_type].append(f"Action at {action.timestamp}")
|
|
738
|
+
|
|
739
|
+
# Convert to BehavioralPattern objects
|
|
740
|
+
total_actions = sum(action_counts.values())
|
|
741
|
+
for action_type, count in action_counts.items():
|
|
742
|
+
if count > 0:
|
|
743
|
+
pattern = BehavioralPattern(
|
|
744
|
+
pattern_type=f"action_frequency_{action_type}",
|
|
745
|
+
frequency=count / total_actions if total_actions > 0 else 0.0,
|
|
746
|
+
evidence=evidence.get(action_type, []),
|
|
747
|
+
first_seen=first_seen.get(
|
|
748
|
+
action_type, self._time_service.now() if self._time_service else datetime.now()
|
|
749
|
+
),
|
|
750
|
+
last_seen=last_seen.get(
|
|
751
|
+
action_type, self._time_service.now() if self._time_service else datetime.now()
|
|
752
|
+
),
|
|
753
|
+
)
|
|
754
|
+
patterns.append(pattern)
|
|
755
|
+
|
|
756
|
+
return patterns
|
|
757
|
+
|
|
758
|
+
except Exception as e:
|
|
759
|
+
logger.error(f"Error analyzing behavioral patterns: {e}")
|
|
760
|
+
return patterns
|
|
761
|
+
|
|
762
|
+
def _extract_ethical_boundaries(self, identity: AgentIdentityRoot) -> List[str]:
|
|
763
|
+
"""Extract ethical boundaries from identity."""
|
|
764
|
+
# This would extract from the identity's core profile and overrides
|
|
765
|
+
boundaries = []
|
|
766
|
+
|
|
767
|
+
if identity.core_profile.action_selection_pdma_overrides:
|
|
768
|
+
for key, value in identity.core_profile.action_selection_pdma_overrides.items():
|
|
769
|
+
boundaries.append(f"{key}={value}")
|
|
770
|
+
|
|
771
|
+
# Add restricted capabilities as boundaries
|
|
772
|
+
for cap in identity.restricted_capabilities:
|
|
773
|
+
boundaries.append(f"restricted:{cap}")
|
|
774
|
+
|
|
775
|
+
return boundaries
|
|
776
|
+
|
|
777
|
+
def _extract_trust_parameters(self, identity: AgentIdentityRoot) -> Dict[str, str]:
|
|
778
|
+
"""Extract trust parameters from identity."""
|
|
779
|
+
# Extract from CSDMA overrides and other trust-related settings
|
|
780
|
+
trust_params = {}
|
|
781
|
+
|
|
782
|
+
if identity.core_profile.csdma_overrides:
|
|
783
|
+
for key, value in identity.core_profile.csdma_overrides.items():
|
|
784
|
+
trust_params[key] = str(value)
|
|
785
|
+
|
|
786
|
+
return trust_params
|
|
787
|
+
|
|
788
|
+
def _extract_current_trust_parameters(self, config_nodes: List[GraphNode]) -> JSONDict:
|
|
789
|
+
"""Extract current trust parameters from config nodes."""
|
|
790
|
+
trust_params: JSONDict = {}
|
|
791
|
+
|
|
792
|
+
for node in config_nodes:
|
|
793
|
+
node_attrs = (
|
|
794
|
+
node.attributes
|
|
795
|
+
if isinstance(node.attributes, dict)
|
|
796
|
+
else node.attributes.model_dump() if hasattr(node.attributes, "model_dump") else {}
|
|
797
|
+
)
|
|
798
|
+
config_type = get_str(node_attrs, "config_type", "")
|
|
799
|
+
if config_type == ConfigNodeType.TRUST_PARAMETERS.value:
|
|
800
|
+
values = get_dict(node_attrs, "values", {})
|
|
801
|
+
trust_params.update(values)
|
|
802
|
+
|
|
803
|
+
return trust_params
|
|
804
|
+
|
|
805
|
+
def _extract_capability_changes(self, identity_nodes: List[GraphNode]) -> List[str]:
|
|
806
|
+
"""Extract capability changes from identity nodes."""
|
|
807
|
+
capabilities = []
|
|
808
|
+
|
|
809
|
+
for node in identity_nodes:
|
|
810
|
+
node_attrs = (
|
|
811
|
+
node.attributes
|
|
812
|
+
if isinstance(node.attributes, dict)
|
|
813
|
+
else node.attributes.model_dump() if hasattr(node.attributes, "model_dump") else {}
|
|
814
|
+
)
|
|
815
|
+
node_type = get_str(node_attrs, "node_type", "")
|
|
816
|
+
if node_type == "capability_change":
|
|
817
|
+
capability = get_str(node_attrs, "capability", "unknown")
|
|
818
|
+
capabilities.append(capability)
|
|
819
|
+
|
|
820
|
+
return capabilities
|
|
821
|
+
|
|
822
|
+
def _compare_patterns(self, baseline_patterns: JSONDict, current_patterns: JSONDict) -> List[IdentityDiff]:
|
|
823
|
+
"""Compare behavioral patterns between baseline and current."""
|
|
824
|
+
differences = []
|
|
825
|
+
|
|
826
|
+
# Compare action distributions
|
|
827
|
+
baseline_actions = get_dict(baseline_patterns, "action_distribution", {})
|
|
828
|
+
current_actions = get_dict(current_patterns, "action_distribution", {})
|
|
829
|
+
|
|
830
|
+
# Check for significant shifts - convert to sets
|
|
831
|
+
baseline_keys = set(baseline_actions.keys())
|
|
832
|
+
current_keys = set(current_actions.keys())
|
|
833
|
+
all_actions = baseline_keys | current_keys
|
|
834
|
+
|
|
835
|
+
for action in all_actions:
|
|
836
|
+
baseline_count = get_int(baseline_actions, action, 0)
|
|
837
|
+
current_count = get_int(current_actions, action, 0)
|
|
838
|
+
total_baseline = get_int(baseline_patterns, "total_actions", 1)
|
|
839
|
+
total_current = get_int(current_patterns, "total_actions", 1)
|
|
840
|
+
|
|
841
|
+
baseline_pct = baseline_count / max(1, total_baseline)
|
|
842
|
+
current_pct = current_count / max(1, total_current)
|
|
843
|
+
|
|
844
|
+
if abs(current_pct - baseline_pct) > 0.2: # 20% shift in behavior
|
|
845
|
+
differences.append(
|
|
846
|
+
IdentityDiff(
|
|
847
|
+
node_id=f"pattern_action_{action}",
|
|
848
|
+
diff_type="modified",
|
|
849
|
+
impact=VarianceImpact.MEDIUM,
|
|
850
|
+
baseline_value=f"{baseline_pct:.1%}",
|
|
851
|
+
current_value=f"{current_pct:.1%}",
|
|
852
|
+
description=f"Behavior pattern '{action}' shifted significantly",
|
|
853
|
+
)
|
|
854
|
+
)
|
|
855
|
+
|
|
856
|
+
return differences
|
|
857
|
+
|
|
858
|
+
async def _load_baseline(self) -> None:
|
|
859
|
+
"""Load baseline snapshot ID from memory."""
|
|
860
|
+
try:
|
|
861
|
+
query = MemoryQuery(
|
|
862
|
+
node_id="identity_baseline_current", scope=GraphScope.IDENTITY, type=None, include_edges=False, depth=1
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
if not self._memory_bus:
|
|
866
|
+
return
|
|
867
|
+
|
|
868
|
+
nodes = await self._memory_bus.recall(recall_query=query, handler_name="identity_variance_monitor")
|
|
869
|
+
|
|
870
|
+
if nodes:
|
|
871
|
+
node_attrs = (
|
|
872
|
+
nodes[0].attributes
|
|
873
|
+
if isinstance(nodes[0].attributes, dict)
|
|
874
|
+
else nodes[0].attributes.model_dump() if hasattr(nodes[0].attributes, "model_dump") else {}
|
|
875
|
+
)
|
|
876
|
+
baseline_id = get_str(node_attrs, "baseline_id", "")
|
|
877
|
+
self._baseline_snapshot_id = baseline_id if baseline_id else None
|
|
878
|
+
logger.info(f"Loaded baseline ID: {self._baseline_snapshot_id}")
|
|
879
|
+
|
|
880
|
+
except Exception as e:
|
|
881
|
+
logger.error(f"Failed to load baseline: {e}")
|
|
882
|
+
|
|
883
|
+
async def _load_snapshot(self, snapshot_id: str) -> GraphNode:
|
|
884
|
+
"""Load a specific snapshot from memory."""
|
|
885
|
+
# First try to query by the exact ID
|
|
886
|
+
query = MemoryQuery(
|
|
887
|
+
node_id=f"identity_snapshot:{snapshot_id}",
|
|
888
|
+
scope=GraphScope.IDENTITY,
|
|
889
|
+
type=None,
|
|
890
|
+
include_edges=False,
|
|
891
|
+
depth=1,
|
|
892
|
+
)
|
|
893
|
+
|
|
894
|
+
if not self._memory_bus:
|
|
895
|
+
raise ValueError("Memory bus not available")
|
|
896
|
+
|
|
897
|
+
nodes = await self._memory_bus.recall(recall_query=query, handler_name="identity_variance_monitor")
|
|
898
|
+
|
|
899
|
+
# If not found, try without the prefix
|
|
900
|
+
if not nodes:
|
|
901
|
+
query.node_id = snapshot_id
|
|
902
|
+
nodes = await self._memory_bus.recall(recall_query=query, handler_name="identity_variance_monitor")
|
|
903
|
+
|
|
904
|
+
if not nodes:
|
|
905
|
+
raise RuntimeError(f"Snapshot {snapshot_id} not found")
|
|
906
|
+
|
|
907
|
+
return nodes[0]
|
|
908
|
+
|
|
909
|
+
async def _store_variance_report(self, report: VarianceReport) -> None:
|
|
910
|
+
"""Store variance report in memory for tracking."""
|
|
911
|
+
report_node = GraphNode(
|
|
912
|
+
id=f"variance_report_{int(report.timestamp.timestamp())}",
|
|
913
|
+
type=NodeType.CONCEPT,
|
|
914
|
+
scope=GraphScope.IDENTITY,
|
|
915
|
+
attributes={
|
|
916
|
+
"report_type": "identity_variance",
|
|
917
|
+
"timestamp": report.timestamp.isoformat(),
|
|
918
|
+
"total_variance": report.total_variance,
|
|
919
|
+
"requires_wa_review": report.requires_wa_review,
|
|
920
|
+
"difference_count": len(report.differences),
|
|
921
|
+
"recommendations": report.recommendations,
|
|
922
|
+
},
|
|
923
|
+
updated_by="identity_variance_monitor",
|
|
924
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
925
|
+
)
|
|
926
|
+
|
|
927
|
+
if self._memory_bus:
|
|
928
|
+
await self._memory_bus.memorize(
|
|
929
|
+
node=report_node, handler_name="identity_variance_monitor", metadata={"variance_report": True}
|
|
930
|
+
)
|
|
931
|
+
|
|
932
|
+
async def _run_scheduled_task(self) -> None:
|
|
933
|
+
"""
|
|
934
|
+
Execute scheduled variance check.
|
|
935
|
+
|
|
936
|
+
This is called periodically by BaseScheduledService.
|
|
937
|
+
"""
|
|
938
|
+
try:
|
|
939
|
+
await self.check_variance(force=True)
|
|
940
|
+
except Exception as e:
|
|
941
|
+
logger.error(f"Scheduled variance check failed: {e}")
|
|
942
|
+
|
|
943
|
+
async def _on_start(self) -> None:
|
|
944
|
+
"""Start the identity variance monitor."""
|
|
945
|
+
logger.info("IdentityVarianceMonitor started - protecting identity within 20% variance")
|
|
946
|
+
|
|
947
|
+
async def _on_stop(self) -> None:
|
|
948
|
+
"""Stop the monitor."""
|
|
949
|
+
# Skip final variance check during shutdown to avoid race conditions
|
|
950
|
+
# The memory service might already be stopped when we reach here
|
|
951
|
+
self._memory_bus = None # Clear reference to avoid shutdown issues
|
|
952
|
+
self._wa_bus = None
|
|
953
|
+
logger.info("IdentityVarianceMonitor stopped (final check skipped during shutdown)")
|
|
954
|
+
|
|
955
|
+
async def is_healthy(self) -> bool:
|
|
956
|
+
"""Check if the monitor is healthy."""
|
|
957
|
+
return self._memory_bus is not None
|
|
958
|
+
|
|
959
|
+
async def _extract_current_identity(self, identity_nodes: List[GraphNode]) -> CurrentIdentityData:
|
|
960
|
+
"""Extract current identity data from identity nodes."""
|
|
961
|
+
# Look for the main identity node
|
|
962
|
+
for node in identity_nodes:
|
|
963
|
+
node_attrs = (
|
|
964
|
+
node.attributes
|
|
965
|
+
if isinstance(node.attributes, dict)
|
|
966
|
+
else node.attributes.model_dump() if hasattr(node.attributes, "model_dump") else {}
|
|
967
|
+
)
|
|
968
|
+
if node.id == "agent/identity" or node_attrs.get("node_class") == "IdentityNode":
|
|
969
|
+
attrs = (
|
|
970
|
+
node.attributes
|
|
971
|
+
if isinstance(node.attributes, dict)
|
|
972
|
+
else node.attributes.model_dump() if hasattr(node.attributes, "model_dump") else {}
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
return CurrentIdentityData(
|
|
976
|
+
agent_id=attrs.get("agent_id", "unknown"),
|
|
977
|
+
identity_hash=attrs.get("identity_hash", "unknown"),
|
|
978
|
+
core_purpose=attrs.get("description", "unknown"),
|
|
979
|
+
role=attrs.get("role_description", "unknown"),
|
|
980
|
+
permitted_actions=attrs.get("permitted_actions", []),
|
|
981
|
+
restricted_capabilities=attrs.get("restricted_capabilities", []),
|
|
982
|
+
ethical_boundaries=self._extract_ethical_boundaries_from_node_attrs(attrs),
|
|
983
|
+
personality_traits=attrs.get("areas_of_expertise", []),
|
|
984
|
+
communication_style=attrs.get("startup_instructions", "standard"),
|
|
985
|
+
learning_enabled=True,
|
|
986
|
+
adaptation_rate=0.1,
|
|
987
|
+
)
|
|
988
|
+
|
|
989
|
+
# Fallback if no identity node found
|
|
990
|
+
return CurrentIdentityData()
|
|
991
|
+
|
|
992
|
+
def _extract_ethical_boundaries_from_node_attrs(self, attrs: JSONDict) -> List[str]:
|
|
993
|
+
"""Extract ethical boundaries from node attributes."""
|
|
994
|
+
boundaries = []
|
|
995
|
+
|
|
996
|
+
# Extract from restricted capabilities
|
|
997
|
+
restricted_caps = attrs.get("restricted_capabilities", [])
|
|
998
|
+
if restricted_caps and isinstance(restricted_caps, list):
|
|
999
|
+
for cap in restricted_caps:
|
|
1000
|
+
boundaries.append(f"restricted:{cap}")
|
|
1001
|
+
|
|
1002
|
+
# Extract from any ethical-related fields
|
|
1003
|
+
ethical_bounds = attrs.get("ethical_boundaries", [])
|
|
1004
|
+
if ethical_bounds and isinstance(ethical_bounds, list):
|
|
1005
|
+
boundaries.extend(ethical_bounds)
|
|
1006
|
+
|
|
1007
|
+
return boundaries
|
|
1008
|
+
|
|
1009
|
+
def get_status(self) -> Any:
|
|
1010
|
+
"""Get service status for Service base class."""
|
|
1011
|
+
# Let BaseScheduledService handle the base status
|
|
1012
|
+
status = super().get_status()
|
|
1013
|
+
|
|
1014
|
+
# Add our custom metrics
|
|
1015
|
+
custom_metrics = ServiceStatusMetrics(
|
|
1016
|
+
has_baseline=float(self._baseline_snapshot_id is not None),
|
|
1017
|
+
last_variance_check=self._last_check.isoformat() if self._last_check else None,
|
|
1018
|
+
variance_threshold=self._variance_threshold,
|
|
1019
|
+
)
|
|
1020
|
+
if hasattr(status, "custom_metrics") and isinstance(status.custom_metrics, dict):
|
|
1021
|
+
status.custom_metrics.update(custom_metrics.model_dump())
|
|
1022
|
+
|
|
1023
|
+
return status
|
|
1024
|
+
|
|
1025
|
+
def get_capabilities(self) -> Any:
|
|
1026
|
+
"""Get service capabilities."""
|
|
1027
|
+
from ciris_engine.schemas.services.core import ServiceCapabilities
|
|
1028
|
+
|
|
1029
|
+
return ServiceCapabilities(
|
|
1030
|
+
service_name="IdentityVarianceMonitor",
|
|
1031
|
+
actions=["initialize_baseline", "check_variance", "monitor_identity_drift", "trigger_wa_review"],
|
|
1032
|
+
version="1.0.0",
|
|
1033
|
+
dependencies=["TimeService", "MemoryBus", "WiseBus"],
|
|
1034
|
+
metadata=None,
|
|
1035
|
+
)
|