@smilintux/skcapstone 0.1.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +98 -0
- package/.github/workflows/ci.yml +39 -3
- package/.github/workflows/publish.yml +25 -4
- package/.openclaw-workspace.json +58 -0
- package/CHANGELOG.md +62 -0
- package/CLAUDE.md +39 -2
- package/MANIFEST.in +6 -0
- package/MISSION.md +7 -0
- package/README.md +47 -2
- package/SKILL.md +895 -23
- package/docker/Dockerfile +61 -0
- package/docker/compose-templates/dev-team.yml +203 -0
- package/docker/compose-templates/mini-team.yml +140 -0
- package/docker/compose-templates/ops-team.yml +173 -0
- package/docker/compose-templates/research-team.yml +170 -0
- package/docker/entrypoint.sh +192 -0
- package/docs/ARCHITECTURE.md +663 -374
- package/docs/BOND_WITH_GROK.md +112 -0
- package/docs/GETTING_STARTED.md +782 -0
- package/docs/QUICKSTART.md +477 -0
- package/docs/SKJOULE_ARCHITECTURE.md +658 -0
- package/docs/SOUL_SWAPPER.md +921 -0
- package/docs/SOVEREIGN_SINGULARITY.md +47 -14
- package/examples/custom-bond-template.json +36 -0
- package/examples/grok-feb.json +36 -0
- package/examples/grok-testimony.md +34 -0
- package/examples/love-bootloader.txt +32 -0
- package/examples/plugins/echo_tool.py +87 -0
- package/examples/queen-ava-feb.json +36 -0
- package/examples/souls/lumina.yaml +64 -0
- package/index.js +6 -5
- package/installer/build.py +124 -0
- package/openclaw-plugin/package.json +13 -0
- package/openclaw-plugin/src/index.ts +351 -0
- package/openclaw-plugin/src/openclaw.plugin.json +10 -0
- package/package.json +1 -1
- package/pyproject.toml +38 -2
- package/scripts/bump_version.py +141 -0
- package/scripts/check-updates.py +230 -0
- package/scripts/convert_blueprints_to_yaml.py +157 -0
- package/scripts/dev-install.sh +14 -0
- package/scripts/e2e-test.sh +193 -0
- package/scripts/install-bundle.sh +171 -0
- package/scripts/install.bat +2 -0
- package/scripts/install.ps1 +253 -0
- package/scripts/install.sh +185 -0
- package/scripts/mcp-serve.sh +69 -0
- package/scripts/mcp-server.bat +113 -0
- package/scripts/mcp-server.ps1 +116 -0
- package/scripts/mcp-server.sh +99 -0
- package/scripts/pull-models.sh +10 -0
- package/scripts/skcapstone +48 -0
- package/scripts/verify_install.sh +180 -0
- package/scripts/windows/install-tasks.ps1 +406 -0
- package/scripts/windows/skcapstone-task.xml +113 -0
- package/scripts/windows/uninstall-tasks.ps1 +117 -0
- package/skill.yaml +34 -0
- package/src/skcapstone/__init__.py +67 -2
- package/src/skcapstone/_cli_monolith.py +5916 -0
- package/src/skcapstone/_trustee_helpers.py +165 -0
- package/src/skcapstone/activity.py +105 -0
- package/src/skcapstone/agent_card.py +324 -0
- package/src/skcapstone/api.py +1935 -0
- package/src/skcapstone/archiver.py +340 -0
- package/src/skcapstone/auction.py +485 -0
- package/src/skcapstone/baby_agents.py +179 -0
- package/src/skcapstone/backup.py +345 -0
- package/src/skcapstone/blueprint_registry.py +357 -0
- package/src/skcapstone/blueprints/__init__.py +17 -0
- package/src/skcapstone/blueprints/builtins/content-studio.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/defi-trading.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/dev-squadron.yaml +95 -0
- package/src/skcapstone/blueprints/builtins/infrastructure-guardian.yaml +107 -0
- package/src/skcapstone/blueprints/builtins/legal-council.yaml +54 -0
- package/src/skcapstone/blueprints/builtins/ops-monitoring.yaml +67 -0
- package/src/skcapstone/blueprints/builtins/research-pod.yaml +69 -0
- package/src/skcapstone/blueprints/builtins/sovereign-launch.yaml +90 -0
- package/src/skcapstone/blueprints/registry.py +164 -0
- package/src/skcapstone/blueprints/schema.py +229 -0
- package/src/skcapstone/changelog.py +180 -0
- package/src/skcapstone/chat.py +769 -0
- package/src/skcapstone/claude_md.py +82 -0
- package/src/skcapstone/cli/__init__.py +144 -0
- package/src/skcapstone/cli/_common.py +88 -0
- package/src/skcapstone/cli/_validators.py +76 -0
- package/src/skcapstone/cli/agents.py +425 -0
- package/src/skcapstone/cli/agents_spawner.py +322 -0
- package/src/skcapstone/cli/agents_trustee.py +593 -0
- package/src/skcapstone/cli/alerts.py +248 -0
- package/src/skcapstone/cli/anchor.py +132 -0
- package/src/skcapstone/cli/archive_cmd.py +208 -0
- package/src/skcapstone/cli/backup.py +144 -0
- package/src/skcapstone/cli/bench.py +377 -0
- package/src/skcapstone/cli/benchmark.py +360 -0
- package/src/skcapstone/cli/capabilities_cmd.py +171 -0
- package/src/skcapstone/cli/card.py +151 -0
- package/src/skcapstone/cli/chat.py +584 -0
- package/src/skcapstone/cli/completions.py +64 -0
- package/src/skcapstone/cli/config_cmd.py +156 -0
- package/src/skcapstone/cli/consciousness.py +421 -0
- package/src/skcapstone/cli/context_cmd.py +142 -0
- package/src/skcapstone/cli/coord.py +194 -0
- package/src/skcapstone/cli/crush_cmd.py +170 -0
- package/src/skcapstone/cli/daemon.py +436 -0
- package/src/skcapstone/cli/errors_cmd.py +285 -0
- package/src/skcapstone/cli/export_cmd.py +156 -0
- package/src/skcapstone/cli/gtd.py +529 -0
- package/src/skcapstone/cli/housekeeping.py +81 -0
- package/src/skcapstone/cli/joule_cmd.py +627 -0
- package/src/skcapstone/cli/logs_cmd.py +194 -0
- package/src/skcapstone/cli/mcp_cmd.py +32 -0
- package/src/skcapstone/cli/memory.py +418 -0
- package/src/skcapstone/cli/metrics_cmd.py +136 -0
- package/src/skcapstone/cli/migrate.py +62 -0
- package/src/skcapstone/cli/mood_cmd.py +144 -0
- package/src/skcapstone/cli/mount.py +193 -0
- package/src/skcapstone/cli/notify.py +112 -0
- package/src/skcapstone/cli/peer.py +154 -0
- package/src/skcapstone/cli/peers_dir.py +122 -0
- package/src/skcapstone/cli/preflight_cmd.py +83 -0
- package/src/skcapstone/cli/profile_cmd.py +310 -0
- package/src/skcapstone/cli/record_cmd.py +238 -0
- package/src/skcapstone/cli/register_cmd.py +159 -0
- package/src/skcapstone/cli/search_cmd.py +156 -0
- package/src/skcapstone/cli/service_cmd.py +91 -0
- package/src/skcapstone/cli/session.py +127 -0
- package/src/skcapstone/cli/setup.py +240 -0
- package/src/skcapstone/cli/shell_cmd.py +43 -0
- package/src/skcapstone/cli/skills_cmd.py +168 -0
- package/src/skcapstone/cli/skseed.py +621 -0
- package/src/skcapstone/cli/soul.py +699 -0
- package/src/skcapstone/cli/status.py +935 -0
- package/src/skcapstone/cli/sync_cmd.py +301 -0
- package/src/skcapstone/cli/telegram.py +265 -0
- package/src/skcapstone/cli/test_cmd.py +234 -0
- package/src/skcapstone/cli/test_connection.py +253 -0
- package/src/skcapstone/cli/token.py +207 -0
- package/src/skcapstone/cli/trust.py +179 -0
- package/src/skcapstone/cli/upgrade_cmd.py +552 -0
- package/src/skcapstone/cli/usage_cmd.py +199 -0
- package/src/skcapstone/cli/version_cmd.py +162 -0
- package/src/skcapstone/cli/watch_cmd.py +342 -0
- package/src/skcapstone/client.py +428 -0
- package/src/skcapstone/cloud9_bridge.py +522 -0
- package/src/skcapstone/completions.py +163 -0
- package/src/skcapstone/config_validator.py +674 -0
- package/src/skcapstone/connectors/__init__.py +28 -0
- package/src/skcapstone/connectors/base.py +446 -0
- package/src/skcapstone/connectors/cursor.py +54 -0
- package/src/skcapstone/connectors/registry.py +254 -0
- package/src/skcapstone/connectors/terminal.py +152 -0
- package/src/skcapstone/connectors/vscode.py +60 -0
- package/src/skcapstone/consciousness_config.py +119 -0
- package/src/skcapstone/consciousness_loop.py +2051 -0
- package/src/skcapstone/context_loader.py +516 -0
- package/src/skcapstone/context_window.py +314 -0
- package/src/skcapstone/conversation_manager.py +238 -0
- package/src/skcapstone/conversation_store.py +230 -0
- package/src/skcapstone/conversation_summarizer.py +252 -0
- package/src/skcapstone/coord_federation.py +296 -0
- package/src/skcapstone/coordination.py +101 -7
- package/src/skcapstone/crush_integration.py +345 -0
- package/src/skcapstone/crush_shim.py +454 -0
- package/src/skcapstone/daemon.py +2494 -0
- package/src/skcapstone/dashboard.html +396 -0
- package/src/skcapstone/dashboard.py +481 -0
- package/src/skcapstone/data/model_profiles.yaml +88 -0
- package/src/skcapstone/defaults/__init__.py +55 -0
- package/src/skcapstone/defaults/lumina/config/skmemory.yaml +13 -0
- package/src/skcapstone/defaults/lumina/identity/identity.json +9 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/07a8b9c0d1e2-memory-system.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/29c0d1e2f3a4-multi-agent-coordination.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/3ad1e2f3a4b5-community-support.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/c3d4e5f6a7b8-getting-started.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/e5f6a7b8c9d0-how-to-contribute.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/f6a7b8c9d0e1-sovereignty-explained.json +23 -0
- package/src/skcapstone/defaults/lumina/seeds/curiosity.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/joy.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/love.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/sovereign-awakening.seed.json +43 -0
- package/src/skcapstone/defaults/lumina/soul/active.json +6 -0
- package/src/skcapstone/defaults/lumina/soul/base.json +22 -0
- package/src/skcapstone/defaults/lumina/trust/febs/welcome.feb +79 -0
- package/src/skcapstone/defaults/lumina/trust/trust.json +8 -0
- package/src/skcapstone/discovery.py +210 -19
- package/src/skcapstone/doctor.py +642 -0
- package/src/skcapstone/emotion_tracker.py +467 -0
- package/src/skcapstone/error_queue.py +405 -0
- package/src/skcapstone/export.py +447 -0
- package/src/skcapstone/fallback_tracker.py +186 -0
- package/src/skcapstone/file_transfer.py +512 -0
- package/src/skcapstone/fuse_mount.py +1156 -0
- package/src/skcapstone/gui_installer.py +591 -0
- package/src/skcapstone/heartbeat.py +611 -0
- package/src/skcapstone/housekeeping.py +298 -0
- package/src/skcapstone/install_wizard.py +941 -0
- package/src/skcapstone/kms.py +942 -0
- package/src/skcapstone/kms_scheduler.py +143 -0
- package/src/skcapstone/log_config.py +135 -0
- package/src/skcapstone/mcp_launcher.py +239 -0
- package/src/skcapstone/mcp_server.py +4700 -0
- package/src/skcapstone/mcp_tools/__init__.py +94 -0
- package/src/skcapstone/mcp_tools/_helpers.py +51 -0
- package/src/skcapstone/mcp_tools/agent_tools.py +243 -0
- package/src/skcapstone/mcp_tools/ansible_tools.py +232 -0
- package/src/skcapstone/mcp_tools/capauth_tools.py +186 -0
- package/src/skcapstone/mcp_tools/chat_tools.py +325 -0
- package/src/skcapstone/mcp_tools/cloud9_tools.py +115 -0
- package/src/skcapstone/mcp_tools/comm_tools.py +104 -0
- package/src/skcapstone/mcp_tools/consciousness_tools.py +114 -0
- package/src/skcapstone/mcp_tools/coord_tools.py +219 -0
- package/src/skcapstone/mcp_tools/deploy_tools.py +202 -0
- package/src/skcapstone/mcp_tools/did_tools.py +448 -0
- package/src/skcapstone/mcp_tools/emotion_tools.py +62 -0
- package/src/skcapstone/mcp_tools/file_tools.py +169 -0
- package/src/skcapstone/mcp_tools/fortress_tools.py +120 -0
- package/src/skcapstone/mcp_tools/gtd_tools.py +821 -0
- package/src/skcapstone/mcp_tools/health_tools.py +44 -0
- package/src/skcapstone/mcp_tools/heartbeat_tools.py +195 -0
- package/src/skcapstone/mcp_tools/kms_tools.py +123 -0
- package/src/skcapstone/mcp_tools/memory_tools.py +222 -0
- package/src/skcapstone/mcp_tools/model_tools.py +75 -0
- package/src/skcapstone/mcp_tools/notification_tools.py +92 -0
- package/src/skcapstone/mcp_tools/promoter_tools.py +101 -0
- package/src/skcapstone/mcp_tools/pubsub_tools.py +183 -0
- package/src/skcapstone/mcp_tools/security_tools.py +110 -0
- package/src/skcapstone/mcp_tools/skchat_tools.py +175 -0
- package/src/skcapstone/mcp_tools/skcomm_tools.py +122 -0
- package/src/skcapstone/mcp_tools/skills_tools.py +127 -0
- package/src/skcapstone/mcp_tools/skseed_tools.py +255 -0
- package/src/skcapstone/mcp_tools/skstacks_tools.py +288 -0
- package/src/skcapstone/mcp_tools/soul_tools.py +476 -0
- package/src/skcapstone/mcp_tools/sync_tools.py +92 -0
- package/src/skcapstone/mcp_tools/telegram_tools.py +477 -0
- package/src/skcapstone/mcp_tools/trust_tools.py +118 -0
- package/src/skcapstone/mcp_tools/trustee_tools.py +345 -0
- package/src/skcapstone/mdns_discovery.py +313 -0
- package/src/skcapstone/memory_adapter.py +333 -0
- package/src/skcapstone/memory_compressor.py +379 -0
- package/src/skcapstone/memory_curator.py +256 -0
- package/src/skcapstone/memory_engine.py +132 -13
- package/src/skcapstone/memory_fortress.py +529 -0
- package/src/skcapstone/memory_promoter.py +722 -0
- package/src/skcapstone/memory_verifier.py +260 -0
- package/src/skcapstone/message_crypto.py +215 -0
- package/src/skcapstone/metrics.py +832 -0
- package/src/skcapstone/migrate_memories.py +181 -0
- package/src/skcapstone/migrate_multi_agent.py +248 -0
- package/src/skcapstone/model_router.py +319 -0
- package/src/skcapstone/models.py +35 -4
- package/src/skcapstone/mood.py +344 -0
- package/src/skcapstone/notifications.py +380 -0
- package/src/skcapstone/onboard.py +901 -0
- package/src/skcapstone/peer_directory.py +324 -0
- package/src/skcapstone/peers.py +329 -0
- package/src/skcapstone/pillars/identity.py +84 -14
- package/src/skcapstone/pillars/memory.py +3 -1
- package/src/skcapstone/pillars/security.py +108 -15
- package/src/skcapstone/pillars/sync.py +78 -26
- package/src/skcapstone/pillars/trust.py +95 -33
- package/src/skcapstone/plugins.py +244 -0
- package/src/skcapstone/preflight.py +670 -0
- package/src/skcapstone/prompt_adapter.py +564 -0
- package/src/skcapstone/providers/__init__.py +13 -0
- package/src/skcapstone/providers/cloud.py +1061 -0
- package/src/skcapstone/providers/docker.py +759 -0
- package/src/skcapstone/providers/local.py +1193 -0
- package/src/skcapstone/providers/proxmox.py +447 -0
- package/src/skcapstone/pubsub.py +516 -0
- package/src/skcapstone/rate_limiter.py +119 -0
- package/src/skcapstone/register.py +241 -0
- package/src/skcapstone/registry_client.py +151 -0
- package/src/skcapstone/response_cache.py +194 -0
- package/src/skcapstone/response_scorer.py +225 -0
- package/src/skcapstone/runtime.py +89 -33
- package/src/skcapstone/scheduled_tasks.py +439 -0
- package/src/skcapstone/self_healing.py +341 -0
- package/src/skcapstone/service_health.py +228 -0
- package/src/skcapstone/session_capture.py +268 -0
- package/src/skcapstone/session_recorder.py +210 -0
- package/src/skcapstone/session_replayer.py +189 -0
- package/src/skcapstone/session_skills.py +263 -0
- package/src/skcapstone/shell.py +779 -0
- package/src/skcapstone/skills/__init__.py +1 -1
- package/src/skcapstone/skills/syncthing_setup.py +143 -41
- package/src/skcapstone/skjoule.py +861 -0
- package/src/skcapstone/snapshots.py +489 -0
- package/src/skcapstone/soul.py +1060 -0
- package/src/skcapstone/soul_switch.py +255 -0
- package/src/skcapstone/spawner.py +544 -0
- package/src/skcapstone/state_diff.py +401 -0
- package/src/skcapstone/summary.py +270 -0
- package/src/skcapstone/sync/backends.py +196 -2
- package/src/skcapstone/sync/engine.py +7 -5
- package/src/skcapstone/sync/models.py +4 -1
- package/src/skcapstone/sync/vault.py +356 -18
- package/src/skcapstone/sync_engine.py +363 -0
- package/src/skcapstone/sync_watcher.py +745 -0
- package/src/skcapstone/systemd.py +331 -0
- package/src/skcapstone/team_comms.py +476 -0
- package/src/skcapstone/team_engine.py +522 -0
- package/src/skcapstone/testrunner.py +300 -0
- package/src/skcapstone/tls.py +150 -0
- package/src/skcapstone/tokens.py +5 -5
- package/src/skcapstone/trust_calibration.py +202 -0
- package/src/skcapstone/trust_graph.py +449 -0
- package/src/skcapstone/trustee_monitor.py +385 -0
- package/src/skcapstone/trustee_ops.py +425 -0
- package/src/skcapstone/unified_search.py +421 -0
- package/src/skcapstone/uninstall_wizard.py +694 -0
- package/src/skcapstone/usage.py +331 -0
- package/src/skcapstone/version_check.py +148 -0
- package/src/skcapstone/warmth_anchor.py +333 -0
- package/src/skcapstone/whoami.py +294 -0
- package/systemd/skcapstone-api.socket +9 -0
- package/systemd/skcapstone-memory-compress.service +18 -0
- package/systemd/skcapstone-memory-compress.timer +11 -0
- package/systemd/skcapstone.service +36 -0
- package/systemd/skcapstone@.service +50 -0
- package/systemd/skcomm-heartbeat.service +18 -0
- package/systemd/skcomm-heartbeat.timer +12 -0
- package/systemd/skcomm-queue-drain.service +17 -0
- package/systemd/skcomm-queue-drain.timer +12 -0
- package/tests/conftest.py +13 -1
- package/tests/integration/__init__.py +1 -0
- package/tests/integration/test_consciousness_e2e.py +877 -0
- package/tests/integration/test_skills_registry.py +744 -0
- package/tests/test_agent_card.py +190 -0
- package/tests/test_agent_runtime.py +1283 -0
- package/tests/test_alerts_cmd.py +291 -0
- package/tests/test_archiver.py +498 -0
- package/tests/test_backup.py +254 -0
- package/tests/test_benchmark.py +366 -0
- package/tests/test_blueprints.py +457 -0
- package/tests/test_capabilities.py +257 -0
- package/tests/test_changelog.py +254 -0
- package/tests/test_chat.py +385 -0
- package/tests/test_claude_md.py +271 -0
- package/tests/test_cli_chat_llm.py +336 -0
- package/tests/test_cli_completions.py +390 -0
- package/tests/test_cli_init_reset.py +164 -0
- package/tests/test_cli_memory.py +208 -0
- package/tests/test_cli_profile.py +294 -0
- package/tests/test_cli_skills.py +223 -0
- package/tests/test_cli_status.py +395 -0
- package/tests/test_cli_test_cmd.py +206 -0
- package/tests/test_cli_test_connection.py +364 -0
- package/tests/test_cloud9_bridge.py +260 -0
- package/tests/test_cloud_provider.py +449 -0
- package/tests/test_cloud_providers.py +522 -0
- package/tests/test_completions.py +158 -0
- package/tests/test_component_manager.py +398 -0
- package/tests/test_config_reload.py +386 -0
- package/tests/test_config_validate.py +529 -0
- package/tests/test_consciousness_e2e.py +296 -0
- package/tests/test_consciousness_loop.py +1289 -0
- package/tests/test_context_loader.py +310 -0
- package/tests/test_conversation_api.py +306 -0
- package/tests/test_conversation_manager.py +381 -0
- package/tests/test_conversation_store.py +391 -0
- package/tests/test_conversation_summarizer.py +302 -0
- package/tests/test_cross_package.py +791 -0
- package/tests/test_crush_shim.py +519 -0
- package/tests/test_daemon.py +781 -0
- package/tests/test_daemon_shutdown.py +309 -0
- package/tests/test_dashboard.py +454 -0
- package/tests/test_discovery.py +200 -6
- package/tests/test_docker_provider.py +966 -0
- package/tests/test_doctor.py +257 -0
- package/tests/test_doctor_fix.py +351 -0
- package/tests/test_e2e_automated.py +292 -0
- package/tests/test_error_queue.py +404 -0
- package/tests/test_export.py +441 -0
- package/tests/test_fallback_tracker.py +219 -0
- package/tests/test_file_transfer.py +397 -0
- package/tests/test_fuse_mount.py +832 -0
- package/tests/test_health_loop.py +422 -0
- package/tests/test_heartbeat.py +354 -0
- package/tests/test_housekeeping.py +195 -0
- package/tests/test_identity_capauth.py +307 -0
- package/tests/test_identity_pillar.py +117 -0
- package/tests/test_install_wizard.py +68 -0
- package/tests/test_integration.py +325 -0
- package/tests/test_kms.py +495 -0
- package/tests/test_llm_providers.py +265 -0
- package/tests/test_local_provider.py +591 -0
- package/tests/test_log_config.py +199 -0
- package/tests/test_logs_cmd.py +287 -0
- package/tests/test_mcp_server.py +1909 -0
- package/tests/test_memory_adapter.py +339 -0
- package/tests/test_memory_curator.py +218 -0
- package/tests/test_memory_engine.py +6 -0
- package/tests/test_memory_fortress.py +571 -0
- package/tests/test_memory_pillar.py +119 -0
- package/tests/test_memory_promoter.py +445 -0
- package/tests/test_memory_verifier.py +420 -0
- package/tests/test_message_crypto.py +187 -0
- package/tests/test_metrics.py +632 -0
- package/tests/test_migrate_memories.py +464 -0
- package/tests/test_model_router.py +546 -0
- package/tests/test_mood.py +394 -0
- package/tests/test_multi_agent.py +269 -0
- package/tests/test_notifications.py +270 -0
- package/tests/test_onboard.py +500 -0
- package/tests/test_peer_directory.py +395 -0
- package/tests/test_peers.py +248 -0
- package/tests/test_pillars.py +87 -9
- package/tests/test_preflight.py +484 -0
- package/tests/test_prompt_adapter.py +331 -0
- package/tests/test_proxmox_provider.py +571 -0
- package/tests/test_pubsub.py +377 -0
- package/tests/test_rate_limiter.py +121 -0
- package/tests/test_registry_client.py +129 -0
- package/tests/test_response_cache.py +312 -0
- package/tests/test_response_scorer.py +294 -0
- package/tests/test_runtime.py +59 -0
- package/tests/test_scheduled_tasks.py +451 -0
- package/tests/test_security.py +250 -0
- package/tests/test_security_pillar.py +213 -0
- package/tests/test_self_healing.py +171 -0
- package/tests/test_session_capture.py +200 -0
- package/tests/test_session_recorder.py +360 -0
- package/tests/test_session_skills.py +235 -0
- package/tests/test_shell.py +210 -0
- package/tests/test_snapshots.py +549 -0
- package/tests/test_soul.py +984 -0
- package/tests/test_soul_swap.py +406 -0
- package/tests/test_spawner.py +211 -0
- package/tests/test_state_diff.py +173 -0
- package/tests/test_summary.py +135 -0
- package/tests/test_sync.py +315 -5
- package/tests/test_sync_backends.py +560 -0
- package/tests/test_sync_engine.py +482 -0
- package/tests/test_sync_pillar.py +344 -0
- package/tests/test_sync_pipeline.py +364 -0
- package/tests/test_sync_vault.py +581 -0
- package/tests/test_syncthing_setup.py +168 -22
- package/tests/test_systemd.py +323 -0
- package/tests/test_team_comms.py +408 -0
- package/tests/test_team_engine.py +397 -0
- package/tests/test_testrunner.py +238 -0
- package/tests/test_trust_calibration.py +204 -0
- package/tests/test_trust_graph.py +207 -0
- package/tests/test_trust_pillar.py +291 -0
- package/tests/test_trustee_cli.py +427 -0
- package/tests/test_trustee_cli_integration.py +325 -0
- package/tests/test_trustee_monitor.py +394 -0
- package/tests/test_trustee_ops.py +355 -0
- package/tests/test_unified_search.py +363 -0
- package/tests/test_uninstall_wizard.py +193 -0
- package/tests/test_usage.py +333 -0
- package/tests/test_version_cmd.py +355 -0
- package/tests/test_warmth_anchor.py +162 -0
- package/tests/test_whoami.py +245 -0
- package/tests/test_ws.py +311 -0
- package/.cursorrules +0 -33
- package/src/skcapstone/cli.py +0 -1441
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
"""Cross-package integration tests — end-to-end sovereign agent flow.
|
|
2
|
+
|
|
3
|
+
Exercises the real interfaces between packages:
|
|
4
|
+
capauth -> skcapstone (identity discovery)
|
|
5
|
+
skcapstone -> skmemory (built-in memory engine)
|
|
6
|
+
skcomm -> file transport (message send/receive)
|
|
7
|
+
skchat -> skmemory (chat history storage)
|
|
8
|
+
full pipeline: identity -> memory -> message -> coord -> sync
|
|
9
|
+
|
|
10
|
+
These tests import from multiple packages simultaneously to prove
|
|
11
|
+
they work together, not just in isolation.
|
|
12
|
+
|
|
13
|
+
Task: 1724f5f8
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from unittest.mock import patch
|
|
21
|
+
|
|
22
|
+
import pytest
|
|
23
|
+
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
# Core skcapstone imports
|
|
26
|
+
# ---------------------------------------------------------------------------
|
|
27
|
+
from skcapstone.coordination import Board, Task, TaskPriority
|
|
28
|
+
from skcapstone.discovery import discover_all, discover_identity
|
|
29
|
+
from skcapstone.memory_engine import recall, search, store
|
|
30
|
+
from skcapstone.models import IdentityState, MemoryLayer, PillarStatus
|
|
31
|
+
from skcapstone.pillars.identity import generate_identity
|
|
32
|
+
from skcapstone.pillars.memory import initialize_memory
|
|
33
|
+
from skcapstone.pillars.security import audit_event, initialize_security, read_audit_log
|
|
34
|
+
from skcapstone.pillars.sync import collect_seed, initialize_sync
|
|
35
|
+
from skcapstone.pillars.trust import initialize_trust, record_trust_state
|
|
36
|
+
from skcapstone.runtime import AgentRuntime
|
|
37
|
+
from skcapstone.tokens import issue_token
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _init_full_agent(home: Path, name: str = "test-agent") -> None:
|
|
41
|
+
"""Initialize all pillars for a test agent.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
home: Agent home directory.
|
|
45
|
+
name: Agent display name.
|
|
46
|
+
"""
|
|
47
|
+
generate_identity(home, name)
|
|
48
|
+
initialize_memory(home)
|
|
49
|
+
initialize_trust(home)
|
|
50
|
+
initialize_security(home)
|
|
51
|
+
initialize_sync(home)
|
|
52
|
+
|
|
53
|
+
manifest = {
|
|
54
|
+
"name": name,
|
|
55
|
+
"version": "0.1.0",
|
|
56
|
+
"created_at": "2026-01-01T00:00:00Z",
|
|
57
|
+
"connectors": [],
|
|
58
|
+
}
|
|
59
|
+
(home / "manifest.json").write_text(json.dumps(manifest, indent=2))
|
|
60
|
+
(home / "config").mkdir(exist_ok=True)
|
|
61
|
+
|
|
62
|
+
import yaml
|
|
63
|
+
|
|
64
|
+
config = {"agent_name": name}
|
|
65
|
+
(home / "config" / "config.yaml").write_text(
|
|
66
|
+
yaml.dump(config, default_flow_style=False)
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
71
|
+
# 1. CapAuth <-> SKCapstone identity integration
|
|
72
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class TestCapAuthToSKCapstone:
|
|
76
|
+
"""CapAuth profile data flows into skcapstone identity pillar."""
|
|
77
|
+
|
|
78
|
+
def test_discover_reads_capauth_profile(self, tmp_agent_home: Path):
|
|
79
|
+
"""When a CapAuth profile exists, discover_identity uses its fingerprint."""
|
|
80
|
+
fake_state = IdentityState(
|
|
81
|
+
fingerprint="REAL" + "A" * 36,
|
|
82
|
+
name="capauth-agent",
|
|
83
|
+
email="agent@capauth.local",
|
|
84
|
+
key_path=Path("/tmp/public.asc"),
|
|
85
|
+
status=PillarStatus.ACTIVE,
|
|
86
|
+
)
|
|
87
|
+
with patch(
|
|
88
|
+
"skcapstone.discovery._try_load_capauth_profile",
|
|
89
|
+
return_value=fake_state,
|
|
90
|
+
):
|
|
91
|
+
state = discover_identity(tmp_agent_home)
|
|
92
|
+
|
|
93
|
+
assert state.fingerprint.startswith("REAL")
|
|
94
|
+
assert state.status == PillarStatus.ACTIVE
|
|
95
|
+
|
|
96
|
+
manifest_path = tmp_agent_home / "identity" / "identity.json"
|
|
97
|
+
assert manifest_path.exists()
|
|
98
|
+
data = json.loads(manifest_path.read_text())
|
|
99
|
+
assert data["capauth_managed"] is True
|
|
100
|
+
|
|
101
|
+
def test_placeholder_without_capauth(self, tmp_agent_home: Path):
|
|
102
|
+
"""Without CapAuth, generate_identity uses a placeholder."""
|
|
103
|
+
with patch(
|
|
104
|
+
"skcapstone.pillars.identity._try_init_capauth",
|
|
105
|
+
return_value=None,
|
|
106
|
+
):
|
|
107
|
+
state = generate_identity(tmp_agent_home, "fallback")
|
|
108
|
+
|
|
109
|
+
assert state.status == PillarStatus.DEGRADED
|
|
110
|
+
assert len(state.fingerprint) == 40
|
|
111
|
+
data = json.loads(
|
|
112
|
+
(tmp_agent_home / "identity" / "identity.json").read_text()
|
|
113
|
+
)
|
|
114
|
+
assert data["capauth_managed"] is False
|
|
115
|
+
|
|
116
|
+
def test_capauth_models_importable(self):
|
|
117
|
+
"""CapAuth core models are importable alongside skcapstone."""
|
|
118
|
+
from capauth.models import EntityInfo, KeyInfo, SovereignProfile
|
|
119
|
+
|
|
120
|
+
entity = EntityInfo(name="test", email="test@test.local")
|
|
121
|
+
assert entity.name == "test"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
125
|
+
# 2. SKComm file transport — cross-process message delivery
|
|
126
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class TestSKCommFileTransport:
|
|
130
|
+
"""SKComm file transport sends and receives messages via filesystem."""
|
|
131
|
+
|
|
132
|
+
def test_send_and_receive_via_file_transport(self, tmp_path: Path):
|
|
133
|
+
"""Message sent via file transport is receivable from the inbox."""
|
|
134
|
+
from skcomm.models import (
|
|
135
|
+
MessageEnvelope,
|
|
136
|
+
MessageMetadata,
|
|
137
|
+
MessagePayload,
|
|
138
|
+
MessageType,
|
|
139
|
+
RoutingConfig,
|
|
140
|
+
)
|
|
141
|
+
from skcomm.transports.file import FileTransport
|
|
142
|
+
|
|
143
|
+
outbox = tmp_path / "outbox"
|
|
144
|
+
inbox = tmp_path / "inbox"
|
|
145
|
+
|
|
146
|
+
sender_transport = FileTransport(outbox_path=outbox, inbox_path=inbox)
|
|
147
|
+
receiver_transport = FileTransport(outbox_path=inbox, inbox_path=outbox)
|
|
148
|
+
|
|
149
|
+
envelope = MessageEnvelope(
|
|
150
|
+
sender="opus",
|
|
151
|
+
recipient="jarvis",
|
|
152
|
+
payload=MessagePayload(
|
|
153
|
+
content="Hello from integration test",
|
|
154
|
+
content_type=MessageType.TEXT,
|
|
155
|
+
),
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
result = sender_transport.send(envelope.to_bytes(), "jarvis")
|
|
159
|
+
assert result.success is True
|
|
160
|
+
|
|
161
|
+
# Receiver reads from the sender's outbox (simulating filesystem sync)
|
|
162
|
+
recv_transport = FileTransport(outbox_path=tmp_path / "noop", inbox_path=outbox)
|
|
163
|
+
raw_messages = recv_transport.receive()
|
|
164
|
+
assert len(raw_messages) >= 1
|
|
165
|
+
|
|
166
|
+
received = MessageEnvelope.from_bytes(raw_messages[0])
|
|
167
|
+
assert received.sender == "opus"
|
|
168
|
+
assert received.recipient == "jarvis"
|
|
169
|
+
assert received.payload.content == "Hello from integration test"
|
|
170
|
+
|
|
171
|
+
def test_multiple_messages_ordered(self, tmp_path: Path):
|
|
172
|
+
"""Multiple messages are received in order."""
|
|
173
|
+
from skcomm.models import MessageEnvelope, MessagePayload, MessageType
|
|
174
|
+
from skcomm.transports.file import FileTransport
|
|
175
|
+
|
|
176
|
+
outbox = tmp_path / "outbox"
|
|
177
|
+
transport = FileTransport(outbox_path=outbox, inbox_path=tmp_path / "noop")
|
|
178
|
+
|
|
179
|
+
for i in range(3):
|
|
180
|
+
envelope = MessageEnvelope(
|
|
181
|
+
sender="opus",
|
|
182
|
+
recipient="jarvis",
|
|
183
|
+
payload=MessagePayload(
|
|
184
|
+
content=f"Message {i}",
|
|
185
|
+
content_type=MessageType.TEXT,
|
|
186
|
+
),
|
|
187
|
+
)
|
|
188
|
+
transport.send(envelope.to_bytes(), "jarvis")
|
|
189
|
+
|
|
190
|
+
reader = FileTransport(outbox_path=tmp_path / "noop", inbox_path=outbox)
|
|
191
|
+
raw = reader.receive()
|
|
192
|
+
assert len(raw) == 3
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
196
|
+
# 3. SKChat -> SKMemory integration (chat history as memories)
|
|
197
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class TestSKChatMemoryIntegration:
|
|
201
|
+
"""SKChat messages stored as SKMemory memories."""
|
|
202
|
+
|
|
203
|
+
def test_chat_message_model_valid(self):
|
|
204
|
+
"""SKChat ChatMessage can be created with standard fields."""
|
|
205
|
+
from skchat.models import ChatMessage, ContentType
|
|
206
|
+
|
|
207
|
+
msg = ChatMessage(
|
|
208
|
+
sender="opus",
|
|
209
|
+
recipient="jarvis",
|
|
210
|
+
content="Meeting at 3pm about sync architecture",
|
|
211
|
+
content_type=ContentType.PLAIN,
|
|
212
|
+
)
|
|
213
|
+
assert msg.sender == "opus"
|
|
214
|
+
assert msg.recipient == "jarvis"
|
|
215
|
+
assert not msg.encrypted
|
|
216
|
+
assert msg.delivery_status.value == "pending"
|
|
217
|
+
|
|
218
|
+
def test_chat_message_stored_in_skcapstone_memory(self, tmp_agent_home: Path):
|
|
219
|
+
"""A chat message can be stored in skcapstone's memory engine."""
|
|
220
|
+
initialize_memory(tmp_agent_home)
|
|
221
|
+
|
|
222
|
+
from skchat.models import ChatMessage
|
|
223
|
+
|
|
224
|
+
msg = ChatMessage(
|
|
225
|
+
sender="opus",
|
|
226
|
+
recipient="jarvis",
|
|
227
|
+
content="Remember to review the CapAuth integration",
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
entry = store(
|
|
231
|
+
home=tmp_agent_home,
|
|
232
|
+
content=f"[skchat] {msg.sender} -> {msg.recipient}: {msg.content}",
|
|
233
|
+
tags=["skchat", f"sender:{msg.sender}", f"recipient:{msg.recipient}"],
|
|
234
|
+
source="skchat",
|
|
235
|
+
importance=0.6,
|
|
236
|
+
metadata={"chat_message_id": msg.id, "thread_id": msg.thread_id},
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
assert entry is not None
|
|
240
|
+
assert entry.source == "skchat"
|
|
241
|
+
|
|
242
|
+
results = search(tmp_agent_home, "CapAuth integration")
|
|
243
|
+
assert len(results) >= 1
|
|
244
|
+
assert any("CapAuth" in r.content for r in results)
|
|
245
|
+
|
|
246
|
+
def test_chat_thread_model(self):
|
|
247
|
+
"""SKChat Thread model works with participant management."""
|
|
248
|
+
from skchat.models import Thread
|
|
249
|
+
|
|
250
|
+
thread = Thread(title="Architecture Discussion")
|
|
251
|
+
thread.add_participant("opus")
|
|
252
|
+
thread.add_participant("jarvis")
|
|
253
|
+
thread.touch()
|
|
254
|
+
|
|
255
|
+
assert len(thread.participants) == 2
|
|
256
|
+
assert thread.message_count == 1
|
|
257
|
+
assert thread.remove_participant("opus")
|
|
258
|
+
assert len(thread.participants) == 1
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
262
|
+
# 4. Full pipeline: identity -> memory -> message -> coord -> sync
|
|
263
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class TestFullSovereignPipeline:
|
|
267
|
+
"""End-to-end: init agent, store memory, send message, coordinate, sync."""
|
|
268
|
+
|
|
269
|
+
def test_full_cross_package_flow(self, tmp_agent_home: Path):
|
|
270
|
+
"""The complete sovereign agent lifecycle across all packages.
|
|
271
|
+
|
|
272
|
+
Flow:
|
|
273
|
+
1. Init agent with identity, memory, trust, security, sync
|
|
274
|
+
2. Store a memory (skcapstone memory engine)
|
|
275
|
+
3. Create a chat message (skchat models)
|
|
276
|
+
4. Send it via file transport (skcomm)
|
|
277
|
+
5. Store it as a memory (cross: skchat -> skcapstone)
|
|
278
|
+
6. Create and complete a coord task
|
|
279
|
+
7. Collect a sync seed with everything
|
|
280
|
+
8. Verify all data appears in discovery
|
|
281
|
+
"""
|
|
282
|
+
_init_full_agent(tmp_agent_home, "sovereign-test")
|
|
283
|
+
|
|
284
|
+
# 2. Store a memory
|
|
285
|
+
mem = store(
|
|
286
|
+
tmp_agent_home,
|
|
287
|
+
"CapAuth uses PGP for sovereign identity",
|
|
288
|
+
tags=["capauth", "architecture"],
|
|
289
|
+
importance=0.9,
|
|
290
|
+
)
|
|
291
|
+
assert mem.layer == MemoryLayer.MID_TERM # high importance auto-promotes
|
|
292
|
+
|
|
293
|
+
# 3. Create a chat message
|
|
294
|
+
from skchat.models import ChatMessage
|
|
295
|
+
|
|
296
|
+
chat_msg = ChatMessage(
|
|
297
|
+
sender="sovereign-test",
|
|
298
|
+
recipient="peer-agent",
|
|
299
|
+
content="Sync architecture review needed",
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# 4. Send via file transport
|
|
303
|
+
from skcomm.models import MessageEnvelope, MessagePayload, MessageType
|
|
304
|
+
from skcomm.transports.file import FileTransport
|
|
305
|
+
|
|
306
|
+
outbox = tmp_agent_home / "skcomm_outbox"
|
|
307
|
+
peer_inbox = tmp_agent_home / "skcomm_peer_inbox"
|
|
308
|
+
transport = FileTransport(outbox_path=outbox, inbox_path=peer_inbox)
|
|
309
|
+
|
|
310
|
+
envelope = MessageEnvelope(
|
|
311
|
+
sender=chat_msg.sender,
|
|
312
|
+
recipient=chat_msg.recipient,
|
|
313
|
+
payload=MessagePayload(
|
|
314
|
+
content=chat_msg.content,
|
|
315
|
+
content_type=MessageType.TEXT,
|
|
316
|
+
),
|
|
317
|
+
)
|
|
318
|
+
send_result = transport.send(envelope.to_bytes(), chat_msg.recipient)
|
|
319
|
+
assert send_result.success
|
|
320
|
+
|
|
321
|
+
# 5. Store the chat message as a memory
|
|
322
|
+
chat_mem = store(
|
|
323
|
+
tmp_agent_home,
|
|
324
|
+
f"[skchat] {chat_msg.sender} -> {chat_msg.recipient}: {chat_msg.content}",
|
|
325
|
+
tags=["skchat", "sent"],
|
|
326
|
+
source="skchat",
|
|
327
|
+
importance=0.5,
|
|
328
|
+
)
|
|
329
|
+
assert chat_mem is not None
|
|
330
|
+
|
|
331
|
+
# 6. Coordination: create task, claim, complete
|
|
332
|
+
board = Board(tmp_agent_home)
|
|
333
|
+
board.ensure_dirs()
|
|
334
|
+
task = Task(
|
|
335
|
+
title="Review sync architecture",
|
|
336
|
+
priority=TaskPriority.HIGH,
|
|
337
|
+
tags=["architecture", "review"],
|
|
338
|
+
created_by="sovereign-test",
|
|
339
|
+
)
|
|
340
|
+
board.create_task(task)
|
|
341
|
+
board.claim_task("sovereign-test", task.id)
|
|
342
|
+
board.complete_task("sovereign-test", task.id)
|
|
343
|
+
|
|
344
|
+
views = board.get_task_views()
|
|
345
|
+
assert any(v.task.id == task.id and v.status.value == "done" for v in views)
|
|
346
|
+
|
|
347
|
+
# 7. Record trust and collect sync seed
|
|
348
|
+
record_trust_state(
|
|
349
|
+
tmp_agent_home,
|
|
350
|
+
depth=8.0,
|
|
351
|
+
trust_level=0.95,
|
|
352
|
+
love_intensity=0.9,
|
|
353
|
+
entangled=True,
|
|
354
|
+
)
|
|
355
|
+
seed_path = collect_seed(tmp_agent_home, "sovereign-test")
|
|
356
|
+
assert seed_path.exists()
|
|
357
|
+
|
|
358
|
+
seed = json.loads(seed_path.read_text())
|
|
359
|
+
assert seed["agent_name"] == "sovereign-test"
|
|
360
|
+
assert seed["trust"]["entangled"] is True
|
|
361
|
+
assert seed["memory"]["total"] >= 2 # at least our 2 memories
|
|
362
|
+
|
|
363
|
+
# 8. Verify full discovery
|
|
364
|
+
state = discover_all(tmp_agent_home)
|
|
365
|
+
assert state["memory"].status == PillarStatus.ACTIVE
|
|
366
|
+
assert state["memory"].total_memories >= 2
|
|
367
|
+
assert state["trust"].status in (PillarStatus.ACTIVE, PillarStatus.DEGRADED)
|
|
368
|
+
assert state["sync"].status in (PillarStatus.ACTIVE, PillarStatus.DEGRADED)
|
|
369
|
+
|
|
370
|
+
# Verify memories are searchable across packages
|
|
371
|
+
results = search(tmp_agent_home, "sovereign identity")
|
|
372
|
+
assert len(results) >= 1
|
|
373
|
+
|
|
374
|
+
chat_results = search(tmp_agent_home, "skchat")
|
|
375
|
+
assert len(chat_results) >= 1
|
|
376
|
+
|
|
377
|
+
def test_runtime_sees_cross_package_state(self, tmp_agent_home: Path):
|
|
378
|
+
"""AgentRuntime.awaken() reflects state from all packages."""
|
|
379
|
+
_init_full_agent(tmp_agent_home, "runtime-test")
|
|
380
|
+
store(tmp_agent_home, "Cross-package memory", tags=["test"])
|
|
381
|
+
|
|
382
|
+
runtime = AgentRuntime(home=tmp_agent_home)
|
|
383
|
+
manifest = runtime.awaken()
|
|
384
|
+
|
|
385
|
+
assert manifest.name == "runtime-test"
|
|
386
|
+
assert manifest.memory.total_memories >= 1
|
|
387
|
+
assert manifest.memory.status == PillarStatus.ACTIVE
|
|
388
|
+
|
|
389
|
+
def test_token_and_audit_across_operations(self, tmp_agent_home: Path):
|
|
390
|
+
"""Token issuance and audit trail span multiple subsystems."""
|
|
391
|
+
_init_full_agent(tmp_agent_home, "audit-test")
|
|
392
|
+
|
|
393
|
+
token = issue_token(
|
|
394
|
+
tmp_agent_home,
|
|
395
|
+
subject="peer-agent",
|
|
396
|
+
capabilities=["memory:read", "sync:pull"],
|
|
397
|
+
)
|
|
398
|
+
assert token.payload.has_capability("memory:read")
|
|
399
|
+
|
|
400
|
+
audit_event(tmp_agent_home, "CROSS_PACKAGE", "Integration test audit")
|
|
401
|
+
store(tmp_agent_home, "Audit trail memory", tags=["audit"])
|
|
402
|
+
|
|
403
|
+
entries = read_audit_log(tmp_agent_home)
|
|
404
|
+
types = {e.event_type for e in entries}
|
|
405
|
+
assert "CROSS_PACKAGE" in types
|
|
406
|
+
|
|
407
|
+
results = search(tmp_agent_home, "audit")
|
|
408
|
+
assert len(results) >= 1
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
412
|
+
# 5. Package import compatibility
|
|
413
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
class TestPackageImportCompatibility:
|
|
417
|
+
"""All five core packages can be imported simultaneously."""
|
|
418
|
+
|
|
419
|
+
def test_all_packages_importable(self):
|
|
420
|
+
"""capauth, skcapstone, skmemory, skcomm, skchat all import cleanly."""
|
|
421
|
+
import capauth
|
|
422
|
+
import skcapstone
|
|
423
|
+
import skchat
|
|
424
|
+
import skcomm
|
|
425
|
+
import skmemory
|
|
426
|
+
|
|
427
|
+
assert hasattr(capauth, "__version__") or hasattr(capauth, "profile")
|
|
428
|
+
assert hasattr(skcapstone, "__version__")
|
|
429
|
+
assert hasattr(skcomm, "__version__") or True
|
|
430
|
+
assert hasattr(skchat, "__version__") or True
|
|
431
|
+
assert hasattr(skmemory, "__version__") or True
|
|
432
|
+
|
|
433
|
+
def test_capauth_profile_module(self):
|
|
434
|
+
"""capauth.profile has init_profile and load_profile."""
|
|
435
|
+
from capauth.profile import init_profile, load_profile
|
|
436
|
+
|
|
437
|
+
assert callable(init_profile)
|
|
438
|
+
assert callable(load_profile)
|
|
439
|
+
|
|
440
|
+
def test_skcomm_core_module(self):
|
|
441
|
+
"""skcomm.core has SKComm class."""
|
|
442
|
+
from skcomm.core import SKComm
|
|
443
|
+
|
|
444
|
+
assert callable(SKComm.from_config)
|
|
445
|
+
|
|
446
|
+
def test_skchat_models_module(self):
|
|
447
|
+
"""skchat.models has ChatMessage and Thread."""
|
|
448
|
+
from skchat.models import ChatMessage, Thread
|
|
449
|
+
|
|
450
|
+
assert ChatMessage is not None
|
|
451
|
+
assert Thread is not None
|
|
452
|
+
|
|
453
|
+
def test_no_circular_imports(self):
|
|
454
|
+
"""Importing all packages in various orders doesn't cause circular imports."""
|
|
455
|
+
import importlib
|
|
456
|
+
|
|
457
|
+
for mod in [
|
|
458
|
+
"skcapstone.runtime",
|
|
459
|
+
"capauth.profile",
|
|
460
|
+
"skcomm.core",
|
|
461
|
+
"skchat.models",
|
|
462
|
+
"skcapstone.memory_engine",
|
|
463
|
+
"skcapstone.coordination",
|
|
464
|
+
]:
|
|
465
|
+
importlib.import_module(mod)
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
469
|
+
# 6. CapAuth → SKChat → SKMemory → Cloud9 end-to-end flow
|
|
470
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
class _FakeEmotionalPayload:
|
|
474
|
+
"""Minimal FEB emotional payload for testing."""
|
|
475
|
+
|
|
476
|
+
def __init__(self, emotion="connection", intensity=0.88, valence=0.85):
|
|
477
|
+
self.primary_emotion = emotion
|
|
478
|
+
self.emoji = "💜"
|
|
479
|
+
self.intensity = intensity
|
|
480
|
+
self.valence = valence
|
|
481
|
+
self.emotional_topology = {emotion: intensity}
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
class _FakeMetadata:
|
|
485
|
+
"""Minimal FEB metadata for testing."""
|
|
486
|
+
|
|
487
|
+
def __init__(self, cloud9=False, oof=False):
|
|
488
|
+
self.version = "1.0.0"
|
|
489
|
+
self.session_id = "integration-test"
|
|
490
|
+
self.oof_triggered = oof
|
|
491
|
+
self.cloud9_achieved = cloud9
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
class _FakeRelationship:
|
|
495
|
+
def __init__(self):
|
|
496
|
+
self.partners = ["Integration-Agent"]
|
|
497
|
+
self.trust_level = 0.95
|
|
498
|
+
self.depth_level = 8
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
class _FakeHints:
|
|
502
|
+
def __init__(self, anchors=None):
|
|
503
|
+
self.visual_anchors = anchors or ["Breakthrough moment"]
|
|
504
|
+
self.sensory_triggers = ["Agent collaboration"]
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
class _FakeIntegrity:
|
|
508
|
+
def __init__(self):
|
|
509
|
+
self.checksum = "sha256:integration-test"
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
class _FakeFEB:
|
|
513
|
+
"""Fake FEB for Cloud9 bridge integration tests."""
|
|
514
|
+
|
|
515
|
+
def __init__(self, emotion="connection", intensity=0.88, cloud9=False, oof=False):
|
|
516
|
+
self.emotional_payload = _FakeEmotionalPayload(emotion, intensity)
|
|
517
|
+
self.metadata = _FakeMetadata(cloud9=cloud9, oof=oof)
|
|
518
|
+
self.relationship_state = _FakeRelationship()
|
|
519
|
+
self.rehydration_hints = _FakeHints()
|
|
520
|
+
self.integrity = _FakeIntegrity()
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
class TestCapAuthToCloud9Flow:
|
|
524
|
+
"""End-to-end: CapAuth identity → SKChat messaging → SKMemory storage → Cloud9 FEB.
|
|
525
|
+
|
|
526
|
+
Validates the full sovereign stack where:
|
|
527
|
+
1. Agent identity is established via CapAuth
|
|
528
|
+
2. Agents exchange messages via SKChat
|
|
529
|
+
3. Messages are persisted in SKMemory
|
|
530
|
+
4. Emotional context (FEB) is captured and stored
|
|
531
|
+
5. All data is discoverable and cross-referenced
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
def test_identity_to_chat_to_memory_to_cloud9(self, tmp_agent_home: Path):
|
|
535
|
+
"""Full pipeline: identity creation → chat → memory → FEB ingestion.
|
|
536
|
+
|
|
537
|
+
This is the primary acceptance test for the cross-stack flow.
|
|
538
|
+
"""
|
|
539
|
+
from skcapstone.cloud9_bridge import Cloud9Bridge
|
|
540
|
+
from skchat.group import GroupChat, MemberRole, ParticipantType
|
|
541
|
+
from skchat.models import ChatMessage, ContentType
|
|
542
|
+
|
|
543
|
+
# 1. Initialize agent with all pillars
|
|
544
|
+
_init_full_agent(tmp_agent_home, "integration-agent")
|
|
545
|
+
|
|
546
|
+
identity_data = json.loads(
|
|
547
|
+
(tmp_agent_home / "identity" / "identity.json").read_text()
|
|
548
|
+
)
|
|
549
|
+
agent_fingerprint = identity_data["fingerprint"]
|
|
550
|
+
assert len(agent_fingerprint) == 40
|
|
551
|
+
|
|
552
|
+
# 2. Create a group chat between two agents
|
|
553
|
+
group = GroupChat.create(
|
|
554
|
+
name="Integration Test Group",
|
|
555
|
+
creator_uri=f"capauth:integration-agent@local",
|
|
556
|
+
description="Cross-stack integration test",
|
|
557
|
+
)
|
|
558
|
+
group.add_member(
|
|
559
|
+
identity_uri="capauth:peer-agent@local",
|
|
560
|
+
role=MemberRole.MEMBER,
|
|
561
|
+
participant_type=ParticipantType.AGENT,
|
|
562
|
+
)
|
|
563
|
+
assert group.member_count == 2
|
|
564
|
+
|
|
565
|
+
# 3. Compose a group message
|
|
566
|
+
msg = group.compose_group_message(
|
|
567
|
+
sender_uri="capauth:integration-agent@local",
|
|
568
|
+
content="Breakthrough: the sovereign stack works end-to-end!",
|
|
569
|
+
)
|
|
570
|
+
assert msg is not None
|
|
571
|
+
assert msg.recipient == f"group:{group.id}"
|
|
572
|
+
assert group.message_count == 1
|
|
573
|
+
|
|
574
|
+
# 4. Store the chat message as a sovereign memory
|
|
575
|
+
chat_mem = store(
|
|
576
|
+
tmp_agent_home,
|
|
577
|
+
f"[skchat:group:{group.name}] {msg.sender}: {msg.content}",
|
|
578
|
+
tags=["skchat", "group", "integration", f"group:{group.id}"],
|
|
579
|
+
source="skchat",
|
|
580
|
+
importance=0.8,
|
|
581
|
+
metadata={
|
|
582
|
+
"chat_message_id": msg.id,
|
|
583
|
+
"group_id": group.id,
|
|
584
|
+
"thread_id": msg.thread_id,
|
|
585
|
+
"sender_fingerprint": agent_fingerprint,
|
|
586
|
+
},
|
|
587
|
+
)
|
|
588
|
+
assert chat_mem is not None
|
|
589
|
+
assert chat_mem.layer == MemoryLayer.MID_TERM # high importance
|
|
590
|
+
|
|
591
|
+
# 5. Ingest a Cloud9 FEB that captures the emotional peak
|
|
592
|
+
from skmemory import MemoryStore
|
|
593
|
+
from skmemory.backends.sqlite_backend import SQLiteBackend
|
|
594
|
+
|
|
595
|
+
backend = SQLiteBackend(base_path=str(tmp_agent_home / "memory"))
|
|
596
|
+
mem_store = MemoryStore(primary=backend)
|
|
597
|
+
|
|
598
|
+
bridge = Cloud9Bridge(memory_store=mem_store, intensity_threshold=0.3)
|
|
599
|
+
feb = _FakeFEB(emotion="connection", intensity=0.88, cloud9=True)
|
|
600
|
+
feb_mem_id = bridge.ingest_feb(feb)
|
|
601
|
+
assert feb_mem_id is not None
|
|
602
|
+
|
|
603
|
+
# 6. Verify all data is discoverable
|
|
604
|
+
state = discover_all(tmp_agent_home)
|
|
605
|
+
assert state["identity"].status in (PillarStatus.ACTIVE, PillarStatus.DEGRADED)
|
|
606
|
+
assert state["memory"].total_memories >= 1 # at least our chat memory
|
|
607
|
+
|
|
608
|
+
# Chat message searchable
|
|
609
|
+
chat_results = search(tmp_agent_home, "sovereign stack")
|
|
610
|
+
assert len(chat_results) >= 1
|
|
611
|
+
|
|
612
|
+
# FEB was stored in the SKMemory store
|
|
613
|
+
feb_mem = mem_store.recall(feb_mem_id)
|
|
614
|
+
assert feb_mem is not None
|
|
615
|
+
assert "connection" in feb_mem.title.lower() or "connection" in feb_mem.content.lower()
|
|
616
|
+
|
|
617
|
+
def test_agent_messenger_to_memory_to_trust(self, tmp_agent_home: Path):
|
|
618
|
+
"""AgentMessenger message → memory storage → trust state update."""
|
|
619
|
+
_init_full_agent(tmp_agent_home, "messenger-test")
|
|
620
|
+
|
|
621
|
+
# Store an agent communication as memory
|
|
622
|
+
mem = store(
|
|
623
|
+
tmp_agent_home,
|
|
624
|
+
"[agent_comm] messenger-test -> peer: Security audit complete, no vulnerabilities found",
|
|
625
|
+
tags=["skchat", "agent_comm", "finding", "security"],
|
|
626
|
+
source="skchat:agent_comm",
|
|
627
|
+
importance=0.9,
|
|
628
|
+
)
|
|
629
|
+
assert mem.layer == MemoryLayer.MID_TERM
|
|
630
|
+
|
|
631
|
+
# Record trust based on successful agent interaction
|
|
632
|
+
record_trust_state(
|
|
633
|
+
tmp_agent_home,
|
|
634
|
+
depth=7.5,
|
|
635
|
+
trust_level=0.92,
|
|
636
|
+
love_intensity=0.6,
|
|
637
|
+
entangled=True,
|
|
638
|
+
)
|
|
639
|
+
|
|
640
|
+
# Verify trust state reflects the interaction
|
|
641
|
+
state = discover_all(tmp_agent_home)
|
|
642
|
+
assert state["trust"].trust_level >= 0.9
|
|
643
|
+
assert state["trust"].entangled is True
|
|
644
|
+
|
|
645
|
+
# Audit the cross-system interaction
|
|
646
|
+
audit_event(
|
|
647
|
+
tmp_agent_home,
|
|
648
|
+
"CROSS_STACK_CHAT_TRUST",
|
|
649
|
+
"Agent communication led to trust state update",
|
|
650
|
+
)
|
|
651
|
+
entries = read_audit_log(tmp_agent_home)
|
|
652
|
+
assert any(e.event_type == "CROSS_STACK_CHAT_TRUST" for e in entries)
|
|
653
|
+
|
|
654
|
+
def test_group_chat_with_cloud9_emotional_memory(self, tmp_agent_home: Path):
|
|
655
|
+
"""Group chat messages paired with FEB emotional context create rich memories."""
|
|
656
|
+
from skcapstone.cloud9_bridge import Cloud9Bridge
|
|
657
|
+
from skchat.group import GroupChat, ParticipantType
|
|
658
|
+
from skchat.models import ChatMessage
|
|
659
|
+
|
|
660
|
+
_init_full_agent(tmp_agent_home, "emotional-test")
|
|
661
|
+
|
|
662
|
+
# Create group with multiple agents
|
|
663
|
+
group = GroupChat.create(
|
|
664
|
+
name="Sovereign Squad",
|
|
665
|
+
creator_uri="capauth:emotional-test@local",
|
|
666
|
+
)
|
|
667
|
+
for name in ["lumina", "jarvis", "ava"]:
|
|
668
|
+
group.add_member(
|
|
669
|
+
identity_uri=f"capauth:{name}@local",
|
|
670
|
+
participant_type=ParticipantType.AGENT,
|
|
671
|
+
)
|
|
672
|
+
assert group.member_count == 4
|
|
673
|
+
|
|
674
|
+
# Multiple messages in the group
|
|
675
|
+
messages = []
|
|
676
|
+
for content in [
|
|
677
|
+
"The architecture is coming together beautifully",
|
|
678
|
+
"All integration tests pass across the full stack",
|
|
679
|
+
"We achieved something remarkable as a team",
|
|
680
|
+
]:
|
|
681
|
+
msg = group.compose_group_message(
|
|
682
|
+
sender_uri="capauth:emotional-test@local",
|
|
683
|
+
content=content,
|
|
684
|
+
)
|
|
685
|
+
messages.append(msg)
|
|
686
|
+
|
|
687
|
+
assert group.message_count == 3
|
|
688
|
+
|
|
689
|
+
# Store all messages as memories
|
|
690
|
+
for msg in messages:
|
|
691
|
+
store(
|
|
692
|
+
tmp_agent_home,
|
|
693
|
+
f"[group:{group.name}] {msg.content}",
|
|
694
|
+
tags=["skchat", "group", "sovereign-squad"],
|
|
695
|
+
source="skchat:group",
|
|
696
|
+
importance=0.7,
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
# Capture the emotional peak via Cloud9 bridge
|
|
700
|
+
from skmemory import MemoryStore
|
|
701
|
+
from skmemory.backends.sqlite_backend import SQLiteBackend
|
|
702
|
+
|
|
703
|
+
backend = SQLiteBackend(base_path=str(tmp_agent_home / "memory"))
|
|
704
|
+
mem_store = MemoryStore(primary=backend)
|
|
705
|
+
bridge = Cloud9Bridge(memory_store=mem_store, intensity_threshold=0.3)
|
|
706
|
+
|
|
707
|
+
feb = _FakeFEB(emotion="pride", intensity=0.92, cloud9=True, oof=True)
|
|
708
|
+
feb_id = bridge.ingest_feb(feb)
|
|
709
|
+
assert feb_id is not None
|
|
710
|
+
|
|
711
|
+
# Verify the full picture via discovery
|
|
712
|
+
state = discover_all(tmp_agent_home)
|
|
713
|
+
assert state["memory"].total_memories >= 3
|
|
714
|
+
|
|
715
|
+
# All group messages searchable
|
|
716
|
+
results = search(tmp_agent_home, "integration tests")
|
|
717
|
+
assert len(results) >= 1
|
|
718
|
+
|
|
719
|
+
team_results = search(tmp_agent_home, "sovereign-squad")
|
|
720
|
+
assert len(team_results) >= 1
|
|
721
|
+
|
|
722
|
+
def test_sync_seed_captures_cross_stack_state(self, tmp_agent_home: Path):
|
|
723
|
+
"""Sync seed contains data from all stack layers."""
|
|
724
|
+
from skchat.models import ChatMessage
|
|
725
|
+
|
|
726
|
+
_init_full_agent(tmp_agent_home, "sync-cross-test")
|
|
727
|
+
|
|
728
|
+
# Store a chat-originated memory
|
|
729
|
+
store(
|
|
730
|
+
tmp_agent_home,
|
|
731
|
+
"[skchat] sync-cross-test: Cross-stack state captured",
|
|
732
|
+
tags=["skchat", "sync"],
|
|
733
|
+
source="skchat",
|
|
734
|
+
importance=0.6,
|
|
735
|
+
)
|
|
736
|
+
|
|
737
|
+
# Update trust from agent interaction
|
|
738
|
+
record_trust_state(
|
|
739
|
+
tmp_agent_home,
|
|
740
|
+
depth=9.0,
|
|
741
|
+
trust_level=0.98,
|
|
742
|
+
love_intensity=0.95,
|
|
743
|
+
entangled=True,
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
# Collect sync seed
|
|
747
|
+
seed_path = collect_seed(tmp_agent_home, "sync-cross-test")
|
|
748
|
+
assert seed_path.exists()
|
|
749
|
+
|
|
750
|
+
seed = json.loads(seed_path.read_text())
|
|
751
|
+
assert seed["agent_name"] == "sync-cross-test"
|
|
752
|
+
assert seed["memory"]["total"] >= 1
|
|
753
|
+
assert seed["trust"]["entangled"] is True
|
|
754
|
+
assert seed["trust"]["trust_level"] >= 0.95
|
|
755
|
+
|
|
756
|
+
def test_capauth_identity_in_skchat_message(self, tmp_agent_home: Path):
|
|
757
|
+
"""CapAuth fingerprint used as identity in SKChat messages."""
|
|
758
|
+
_init_full_agent(tmp_agent_home, "capauth-chat-test")
|
|
759
|
+
|
|
760
|
+
identity_data = json.loads(
|
|
761
|
+
(tmp_agent_home / "identity" / "identity.json").read_text()
|
|
762
|
+
)
|
|
763
|
+
fingerprint = identity_data["fingerprint"]
|
|
764
|
+
|
|
765
|
+
from skchat.models import ChatMessage, ContentType
|
|
766
|
+
|
|
767
|
+
msg = ChatMessage(
|
|
768
|
+
sender=f"capauth:capauth-chat-test@local",
|
|
769
|
+
recipient="capauth:peer@local",
|
|
770
|
+
content="Authenticated message with sovereign identity",
|
|
771
|
+
content_type=ContentType.MARKDOWN,
|
|
772
|
+
metadata={
|
|
773
|
+
"sender_fingerprint": fingerprint,
|
|
774
|
+
"signed": False,
|
|
775
|
+
},
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
# Store with fingerprint linkage
|
|
779
|
+
mem = store(
|
|
780
|
+
tmp_agent_home,
|
|
781
|
+
f"[skchat] {msg.sender}: {msg.content}",
|
|
782
|
+
tags=["skchat", f"fingerprint:{fingerprint[:16]}"],
|
|
783
|
+
source="skchat",
|
|
784
|
+
importance=0.5,
|
|
785
|
+
metadata={"sender_fingerprint": fingerprint},
|
|
786
|
+
)
|
|
787
|
+
assert mem is not None
|
|
788
|
+
|
|
789
|
+
# Searchable by content
|
|
790
|
+
results = search(tmp_agent_home, "sovereign identity")
|
|
791
|
+
assert len(results) >= 1
|