conscio 2.2.2__tar.gz → 2.3.0__tar.gz
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.
- {conscio-2.2.2 → conscio-2.3.0}/CHANGELOG.md +21 -0
- {conscio-2.2.2/conscio.egg-info → conscio-2.3.0}/PKG-INFO +4 -3
- {conscio-2.2.2 → conscio-2.3.0}/README.md +3 -2
- {conscio-2.2.2 → conscio-2.3.0}/conscio/__init__.py +1 -1
- conscio-2.3.0/conscio/agency/promote.py +55 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/skills.py +20 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/cli.py +45 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/engine.py +73 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/quarantine.py +30 -4
- {conscio-2.2.2 → conscio-2.3.0/conscio.egg-info}/PKG-INFO +4 -3
- {conscio-2.2.2 → conscio-2.3.0}/conscio.egg-info/SOURCES.txt +6 -0
- conscio-2.3.0/tests/test_agency_promote.py +56 -0
- conscio-2.3.0/tests/test_cli_promote.py +45 -0
- conscio-2.3.0/tests/test_engine_promote.py +194 -0
- conscio-2.3.0/tests/test_quarantine_promote.py +66 -0
- conscio-2.3.0/tests/test_skills_graft.py +55 -0
- {conscio-2.2.2 → conscio-2.3.0}/LICENSE +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/MANIFEST.in +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/__main__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/adapter_config.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/__init__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/act.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/actor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/adapter.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/adapters.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/breaker.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/contracts.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/fingerprint.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/gateway.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/grammar.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/host_act.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/ledger.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/loop.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/profiles.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/skeptic.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/tools.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/trial.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/agency/trust.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/auto_evolution.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/axis_pack.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/bench.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/coherence.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/content_layer.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/content_store.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/context_manager.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/daemon.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/dreaming.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/event_bus.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/goal_generator.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/guards.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/__init__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/config.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/model_test.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/providers.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/server.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/static/app.js +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/static/index.html +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/hub/static/style.css +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/inner_monologue.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/mcp/__init__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/mcp/jsonrpc.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/mcp/protocol.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/mcp/schemas.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/mcp/seen.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/mcp/server.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/meta_cognition.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/metabolic.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/migrate.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/models.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/__init__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/artifact.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/audit.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/catalog.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/cli.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/identity.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/importer.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/paths.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/publish.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/record.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/record_catalog.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/noosphere/record_publish.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/output_filter.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/perception/__init__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/perception/agent_sensor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/perception/host_sensor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/perception/sensor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/plugins.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/presets/__init__.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/py.typed +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/risk.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/self_prompt.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/semantic.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/session_lifecycle.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/session_rag.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/session_rag_factory.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/shard_engine.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/structural.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/structural_consent.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/structural_drift.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/timeutil.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/token_tracker.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/voice_preset.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/workspace.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio/world_model.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio.egg-info/dependency_links.txt +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio.egg-info/entry_points.txt +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio.egg-info/requires.txt +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/conscio.egg-info/top_level.txt +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/pyproject.toml +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/setup.cfg +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_adapter_config.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_adapter_config_api_key_env.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_act.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_act_immunity.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_actor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_adapter.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_adapters_http.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_adversarial.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_arbiter.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_bench.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_breaker.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_contracts.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_engine_immunity.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_gateway.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_grammar.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_host_act.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_ledger.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_ledger_v201.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_loop.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_no_network.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_profiles.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_skeptic.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_skills.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_skills_wiring.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_state.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_tools.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_tools_manifest.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_trial.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_trust.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agency_volition.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_agent_sensor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_auto_evolution.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_awake.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_axis_pack.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_axis_pack_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_cli.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_cli_trial.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_coherence.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_coherence_engine_integration.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_coherence_state.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_consciousness.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_content_layer.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_content_layer_manager.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_content_store.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_content_store_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_content_store_r05.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_contradiction_detector.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_daemon.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_daemon_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_daemon_config.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_daemon_heartbeat.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_daemon_structure_sync.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_dream_coherence.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_dream_distill.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_dream_reconcile.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_dreaming.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_dreaming_friction.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_durable_guards.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_embedder.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_advisory.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_host_act.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_init.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_meta_reflect.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_propose.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_recall.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_engine_trial.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_event_bus.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_event_bus_act_result.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_event_bus_purge.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_examples.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_goal_provenance.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_goal_source.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_host_sensor.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_hub_config.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_hub_model_test.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_hub_providers.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_hub_server.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_loop_failure_brake.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_adapter_parity.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_fuzz.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_jsonrpc.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_package.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_protocol.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_schemas.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_seen.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_server.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_mcp_server_cli.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_metabolic.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_migrate.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_model_auto_detect.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_model_offline_default.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_artifact.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_audit.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_audit_integration.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_catalog.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_cli.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_engine_free.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_fingerprint.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_identity.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_importer.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_integration.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_parity.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_paths.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_publish.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_quarantine.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_record.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_record_catalog.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_noosphere_record_publish.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_ontological_semantic.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_output_filter.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_output_filter_stages.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_packaging.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_perception.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_perf_reflection.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_plugins.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_quarantine_trial.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_recursive_loop_integration.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_risk.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_self_prompt.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_self_prompt_state.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_semantic_dedup.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_semantic_engine.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_semantic_reconcile_integration.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_session_lifecycle.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_session_lifecycle_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_session_lifecycle_dream.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_session_rag.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_shard_engine.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_state_loaders_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_state_persistence_battery.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_structural.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_structural_consent.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_structural_drift.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_structural_inject.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_timeutil.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_token_tracker.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_trajectory_vector.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_v2_debt_zero.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_voice_preset.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_workspace.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_world_contradictions.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_world_model_entropy.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_world_model_prediction.py +0 -0
- {conscio-2.2.2 → conscio-2.3.0}/tests/test_world_model_prune.py +0 -0
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [2.3.0] - 2026-06-23 — "Promotion"
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Promotion-to-live.** `conscio promote --storage DIR --quarantine ROWID
|
|
14
|
+
--enable-promote` graduates a quarantined foreign skill that has earned
|
|
15
|
+
**≥ 3 clean local trials** (v2.2.2) into the live `SkillLibrary`, seeded with
|
|
16
|
+
the counters it earned **locally** in the sandbox — never the origin's
|
|
17
|
+
(stripped) stats, so no trust is inherited. Engine-side
|
|
18
|
+
(`engine.promote_quarantined`); the noosphere package stays engine-free and
|
|
19
|
+
read-only on `conscio.db`.
|
|
20
|
+
- **Tool-existence check** (deferred from v2.2). Promotion refuses a skill
|
|
21
|
+
whose plan names a tool this instance's live registry does not have.
|
|
22
|
+
- `SkillLibrary.graft` — the single foreign-skill write seam
|
|
23
|
+
(`ON CONFLICT(goal_fp, tool_seq) DO NOTHING`; never overwrites a local skill).
|
|
24
|
+
- Quarantine rows gain `promoted_ts` / `promoted_skill_id` (idempotency +
|
|
25
|
+
audit). Promotion re-checks the content hash (tamper → refuse, no write) and
|
|
26
|
+
is idempotent. `--enable-promote` is required, default off, and **independent
|
|
27
|
+
of** `--enable-trial` / `--enable-act`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
10
31
|
## [2.2.2] - 2026-06-22 — "Trial / execution path"
|
|
11
32
|
|
|
12
33
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: conscio
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Self-awareness framework for AI agents — emergent consciousness via context-aware memory, introspection, and goal generation
|
|
5
5
|
Author-email: Neguiolidas <neguitech@proton.me>
|
|
6
6
|
License: MIT
|
|
@@ -46,8 +46,9 @@ nothing else). It is designed to make small, local models punch far above their
|
|
|
46
46
|
size by giving them memory, self-judgment, and procedural skill — and to prove
|
|
47
47
|
that claim by measurement, not assertion.
|
|
48
48
|
|
|
49
|
-
- **Current release:** `v2.
|
|
50
|
-
- **Prior:** `v2.2.
|
|
49
|
+
- **Current release:** `v2.3.0` — "Promotion": a quarantined skill that has earned **≥ 3 clean local trials** can now be **graduated into the live skill library**. `conscio promote --quarantine ROWID --enable-promote` re-checks the content hash, verifies every tool in the plan exists locally (**tool-existence check**), and grafts the skill seeded with the counters it earned in the sandbox — **never the origin's stats**, so no trust is inherited. Engine-side write; the noosphere stays engine-free and read-only on `conscio.db`. Never overwrites a local skill; idempotent; off by default and independent of `--enable-trial`/`--enable-act`. `pip install conscio`.
|
|
50
|
+
- **Prior:** `v2.2.2` — "Trial / execution path": a quarantined imported skill can **prove itself locally** before promotion — `conscio trial --quarantine ROWID --enable-trial` replays the fixed foreign plan in a **throwaway, fs-only sandbox** through the full safety stack (`validate → precheck → HIGH-block → Skeptic → dispatch`), recording a binary pass/fail on the quarantine row. Fully **isolated** — never writes the live agent's ledger/skills/trust/breaker; tamper refuses without counting. Off by default; independent of `--enable-act`.
|
|
51
|
+
- **Earlier:** `v2.2.1` — "Mutual audit": an instance publishes a non-sensitive projection of its action ledger (`conscio noosphere publish-record`) to the host-shared `noosphere.db`, and a peer **independently audits** it (`conscio noosphere audit`) — deterministic, read-only, engine-free. The auditor re-derives track-record, breaker quarantines, and a foreign-trust level under its **own** thresholds (parity-tested against the engine) and runs a discipline check (did the peer execute actions its own Skeptic FAILed?). No inherited trust; report-only; the auditor persists nothing.
|
|
51
52
|
- **Earlier:** `v2.2.0` — "Society" (Noosphere Core): same-host Conscio instances **share locally-proven skills as data**. `conscio noosphere publish` copies your proven skills (stats stripped) into a host-shared `noosphere.db`; `conscio noosphere import` pulls another instance's skills into a local **quarantine** after execution-free static revalidation. Engine-free; opens your live `conscio.db` **read-only**; zero network/socket. Nothing imported is trusted, served, executed, or promoted — trust is never inherited.
|
|
52
53
|
- **Earlier:** `v2.1.0` — "Hub": a **localhost stdlib HTTP control plane** (`conscio-hub`) to swap the active model/provider and register custom OpenAI-compatible providers without hand-editing JSON. Engine-free; config applies on next boot. Per-provider model auto-discovery; one-shot smoke test before save. `api_key_env` resolution (env var name → value at adapter build time) is now additive to raw `api_key` — daemon + MCP inherit it. Hub never returns a raw API key.
|
|
53
54
|
- **Earlier:** `v2.0.1` — "Connect" continued: **opt-in, host-executed audited `act` over MCP**. Conscio audits + gates + ledgers an action and returns an *execution packet*; the **host** executes and reports the outcome back — Conscio still never touches the world. Off by default (`conscio-mcp --enable-act`, requires the engine **Awake**); the host declares its tool manifest (`name`/`params`/`risk`/`approval_policy`) in `initialize`; HIGH-risk / `require_approval` actions stay **queued for human/Hermes approval** (`conscio.pending` → `conscio.approve`). Also: `conscio-mcp` adapter parity (six providers from config) and the **R-05** content-store dedup fix — shipping **debt-zero**. Cognition (`reflect()`) untouched; purely additive.
|
|
@@ -11,8 +11,9 @@ nothing else). It is designed to make small, local models punch far above their
|
|
|
11
11
|
size by giving them memory, self-judgment, and procedural skill — and to prove
|
|
12
12
|
that claim by measurement, not assertion.
|
|
13
13
|
|
|
14
|
-
- **Current release:** `v2.
|
|
15
|
-
- **Prior:** `v2.2.
|
|
14
|
+
- **Current release:** `v2.3.0` — "Promotion": a quarantined skill that has earned **≥ 3 clean local trials** can now be **graduated into the live skill library**. `conscio promote --quarantine ROWID --enable-promote` re-checks the content hash, verifies every tool in the plan exists locally (**tool-existence check**), and grafts the skill seeded with the counters it earned in the sandbox — **never the origin's stats**, so no trust is inherited. Engine-side write; the noosphere stays engine-free and read-only on `conscio.db`. Never overwrites a local skill; idempotent; off by default and independent of `--enable-trial`/`--enable-act`. `pip install conscio`.
|
|
15
|
+
- **Prior:** `v2.2.2` — "Trial / execution path": a quarantined imported skill can **prove itself locally** before promotion — `conscio trial --quarantine ROWID --enable-trial` replays the fixed foreign plan in a **throwaway, fs-only sandbox** through the full safety stack (`validate → precheck → HIGH-block → Skeptic → dispatch`), recording a binary pass/fail on the quarantine row. Fully **isolated** — never writes the live agent's ledger/skills/trust/breaker; tamper refuses without counting. Off by default; independent of `--enable-act`.
|
|
16
|
+
- **Earlier:** `v2.2.1` — "Mutual audit": an instance publishes a non-sensitive projection of its action ledger (`conscio noosphere publish-record`) to the host-shared `noosphere.db`, and a peer **independently audits** it (`conscio noosphere audit`) — deterministic, read-only, engine-free. The auditor re-derives track-record, breaker quarantines, and a foreign-trust level under its **own** thresholds (parity-tested against the engine) and runs a discipline check (did the peer execute actions its own Skeptic FAILed?). No inherited trust; report-only; the auditor persists nothing.
|
|
16
17
|
- **Earlier:** `v2.2.0` — "Society" (Noosphere Core): same-host Conscio instances **share locally-proven skills as data**. `conscio noosphere publish` copies your proven skills (stats stripped) into a host-shared `noosphere.db`; `conscio noosphere import` pulls another instance's skills into a local **quarantine** after execution-free static revalidation. Engine-free; opens your live `conscio.db` **read-only**; zero network/socket. Nothing imported is trusted, served, executed, or promoted — trust is never inherited.
|
|
17
18
|
- **Earlier:** `v2.1.0` — "Hub": a **localhost stdlib HTTP control plane** (`conscio-hub`) to swap the active model/provider and register custom OpenAI-compatible providers without hand-editing JSON. Engine-free; config applies on next boot. Per-provider model auto-discovery; one-shot smoke test before save. `api_key_env` resolution (env var name → value at adapter build time) is now additive to raw `api_key` — daemon + MCP inherit it. Hub never returns a raw API key.
|
|
18
19
|
- **Earlier:** `v2.0.1` — "Connect" continued: **opt-in, host-executed audited `act` over MCP**. Conscio audits + gates + ledgers an action and returns an *execution packet*; the **host** executes and reports the outcome back — Conscio still never touches the world. Off by default (`conscio-mcp --enable-act`, requires the engine **Awake**); the host declares its tool manifest (`name`/`params`/`risk`/`approval_policy`) in `initialize`; HIGH-risk / `require_approval` actions stay **queued for human/Hermes approval** (`conscio.pending` → `conscio.approve`). Also: `conscio-mcp` adapter parity (six providers from config) and the **R-05** content-store dedup fix — shipping **debt-zero**. Cognition (`reflect()`) untouched; purely additive.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# conscio/agency/promote.py
|
|
2
|
+
"""Promotion gate for a quarantined foreign skill (v2.3.0).
|
|
3
|
+
|
|
4
|
+
A pure mechanic: given a quarantined row's trial counters and tool sequence,
|
|
5
|
+
decide whether it has earned graduation into the live SkillLibrary. Imports
|
|
6
|
+
nothing from conscio.noosphere or conscio.engine. The caller (the engine) owns
|
|
7
|
+
the read of the quarantine row, the graft into the library, and the
|
|
8
|
+
promoted-stamp; this module only judges."""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
MIN_PROMOTE_PASSES = 3 # clean local trials required before graduation
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class PromoteResult:
|
|
20
|
+
skill_id: int
|
|
21
|
+
successes: int
|
|
22
|
+
failures: int
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class PromoteRefusal:
|
|
27
|
+
reason: str
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class PromoteDecision:
|
|
32
|
+
ok: bool
|
|
33
|
+
reason: str # "" when ok
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def evaluate_promotion(*, trial_successes: int, trial_failures: int,
|
|
37
|
+
tool_seq: str, registry: Any) -> PromoteDecision:
|
|
38
|
+
"""Gate a quarantined row for promotion. Order: enough clean passes, zero
|
|
39
|
+
failures, decodable tool_seq, every tool present in the live registry."""
|
|
40
|
+
if trial_successes < MIN_PROMOTE_PASSES:
|
|
41
|
+
return PromoteDecision(
|
|
42
|
+
False,
|
|
43
|
+
f"insufficient trials ({trial_successes}/{MIN_PROMOTE_PASSES})")
|
|
44
|
+
if trial_failures != 0:
|
|
45
|
+
return PromoteDecision(False, f"failed {trial_failures} trial(s)")
|
|
46
|
+
try:
|
|
47
|
+
tools = json.loads(tool_seq)
|
|
48
|
+
if not isinstance(tools, list):
|
|
49
|
+
raise ValueError("tool_seq is not a list")
|
|
50
|
+
except (ValueError, TypeError) as exc:
|
|
51
|
+
return PromoteDecision(False, f"corrupt tool_seq: {exc}")
|
|
52
|
+
for tool in tools:
|
|
53
|
+
if registry.get(str(tool)) is None:
|
|
54
|
+
return PromoteDecision(False, f"unknown tool '{tool}'")
|
|
55
|
+
return PromoteDecision(True, "")
|
|
@@ -166,6 +166,26 @@ class SkillLibrary:
|
|
|
166
166
|
[(skill_id,) for skill_id in served])
|
|
167
167
|
self._conn.commit()
|
|
168
168
|
|
|
169
|
+
# ── promotion (v2.3) ────────────────────────────────────────────────
|
|
170
|
+
|
|
171
|
+
def graft(self, goal_fp: str, goal_text: str, tool_seq: str,
|
|
172
|
+
plan_template: str, *, successes: int,
|
|
173
|
+
failures: int) -> int | None:
|
|
174
|
+
"""Insert a promoted foreign skill as data, seeded with the trial
|
|
175
|
+
counters it earned locally. The single write seam for foreign skills.
|
|
176
|
+
Never overwrites a local skill sharing (goal_fp, tool_seq): a collision
|
|
177
|
+
returns None."""
|
|
178
|
+
cur = self._conn.execute(
|
|
179
|
+
"INSERT INTO skills (created_ts, goal_fp, goal_text, tool_seq,"
|
|
180
|
+
" plan_template, successes, failures) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
181
|
+
" ON CONFLICT(goal_fp, tool_seq) DO NOTHING",
|
|
182
|
+
(time.time(), goal_fp, goal_text, tool_seq, plan_template,
|
|
183
|
+
successes, failures))
|
|
184
|
+
self._conn.commit()
|
|
185
|
+
if cur.rowcount == 0 or cur.lastrowid is None:
|
|
186
|
+
return None
|
|
187
|
+
return int(cur.lastrowid)
|
|
188
|
+
|
|
169
189
|
# ── rendering ──────────────────────────────────────────────────────
|
|
170
190
|
|
|
171
191
|
@staticmethod
|
|
@@ -80,6 +80,18 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
80
80
|
"--enable-trial", action="store_true",
|
|
81
81
|
help="required: actually run the sandboxed trial (off by default)")
|
|
82
82
|
|
|
83
|
+
p_promote = sub.add_parser(
|
|
84
|
+
"promote",
|
|
85
|
+
help="promote a trialed quarantined skill into the live library")
|
|
86
|
+
p_promote.add_argument("--storage", default="",
|
|
87
|
+
help="instance storage dir (default: ~/.hermes)")
|
|
88
|
+
p_promote.add_argument("--quarantine", type=int, required=True,
|
|
89
|
+
metavar="ROWID",
|
|
90
|
+
help="quarantine row id to promote")
|
|
91
|
+
p_promote.add_argument(
|
|
92
|
+
"--enable-promote", action="store_true",
|
|
93
|
+
help="required: actually write to the live library (off by default)")
|
|
94
|
+
|
|
83
95
|
# Listed for discoverability; routed to conscio.{bench,daemon} before argparse.
|
|
84
96
|
sub.add_parser("bench", add_help=False,
|
|
85
97
|
help="measure an inference backend (see: conscio bench --help)")
|
|
@@ -292,6 +304,36 @@ def _cmd_trial(model: str, storage: str, quarantine_id: int,
|
|
|
292
304
|
return 0
|
|
293
305
|
|
|
294
306
|
|
|
307
|
+
def _run_promote(*, storage: str, quarantine_id: int, enable_promote: bool):
|
|
308
|
+
"""Build a bare engine (no adapter — promotion never decodes) and promote
|
|
309
|
+
one quarantined skill. The single seam the CLI tests monkeypatch."""
|
|
310
|
+
from .engine import ConsciousnessEngine
|
|
311
|
+
eng = ConsciousnessEngine(model_name=DEFAULT_MODEL,
|
|
312
|
+
storage_path=_storage(storage))
|
|
313
|
+
try:
|
|
314
|
+
return eng.promote_quarantined(quarantine_id,
|
|
315
|
+
enable_promote=enable_promote)
|
|
316
|
+
finally:
|
|
317
|
+
eng.close()
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def _cmd_promote(storage: str, quarantine_id: int,
|
|
321
|
+
enable_promote: bool) -> int:
|
|
322
|
+
from .agency.promote import PromoteResult
|
|
323
|
+
try:
|
|
324
|
+
outcome = _run_promote(storage=storage, quarantine_id=quarantine_id,
|
|
325
|
+
enable_promote=enable_promote)
|
|
326
|
+
except Exception as exc: # engine wiring failure
|
|
327
|
+
print(f"error: {exc}")
|
|
328
|
+
return 1
|
|
329
|
+
if isinstance(outcome, PromoteResult):
|
|
330
|
+
print(f"PROMOTED skill #{outcome.skill_id} "
|
|
331
|
+
f"(seeded {outcome.successes}/{outcome.failures})")
|
|
332
|
+
return 0
|
|
333
|
+
print(f"PROMOTE REFUSED: {outcome.reason}")
|
|
334
|
+
return 1
|
|
335
|
+
|
|
336
|
+
|
|
295
337
|
def main(argv: list[str] | None = None) -> int:
|
|
296
338
|
argv = list(sys.argv[1:] if argv is None else argv)
|
|
297
339
|
|
|
@@ -330,6 +372,9 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
330
372
|
if args.command == "trial":
|
|
331
373
|
return _cmd_trial(args.model, args.storage, args.quarantine,
|
|
332
374
|
args.enable_trial)
|
|
375
|
+
if args.command == "promote":
|
|
376
|
+
return _cmd_promote(args.storage, args.quarantine,
|
|
377
|
+
args.enable_promote)
|
|
333
378
|
|
|
334
379
|
parser.print_help()
|
|
335
380
|
return 2
|
|
@@ -1064,6 +1064,79 @@ class ConsciousnessEngine:
|
|
|
1064
1064
|
ts=time.time())
|
|
1065
1065
|
return outcome
|
|
1066
1066
|
|
|
1067
|
+
# --- v2.3 "Promotion": graduate a quarantined skill into the library ---
|
|
1068
|
+
|
|
1069
|
+
def promote_quarantined(self, rowid: int, *, enable_promote: bool = False):
|
|
1070
|
+
"""Graduate a quarantined foreign skill that has earned >= 3 clean
|
|
1071
|
+
local trials into the live SkillLibrary, seeded with its trial
|
|
1072
|
+
counters. No adapter, no sandbox, no execution: a data gate that reads
|
|
1073
|
+
the trial evidence and writes one row. Default off.
|
|
1074
|
+
|
|
1075
|
+
Unlike trial (which records a tamper via note_trial), promotion refuses
|
|
1076
|
+
a tampered/already-promoted/gate-failed row WITHOUT writing anything —
|
|
1077
|
+
it only ever writes on a successful graft (the skills row + the
|
|
1078
|
+
promoted-stamp). A refusal leaves the quarantine row untouched.
|
|
1079
|
+
|
|
1080
|
+
Returns a promote.PromoteResult (promoted) or promote.PromoteRefusal."""
|
|
1081
|
+
import time
|
|
1082
|
+
|
|
1083
|
+
from .agency import promote as promote_mod
|
|
1084
|
+
from .agency.skills import SkillLibrary
|
|
1085
|
+
from .agency.tools import make_default_registry
|
|
1086
|
+
from .noosphere import artifact, quarantine
|
|
1087
|
+
from .noosphere.paths import quarantine_db_path
|
|
1088
|
+
|
|
1089
|
+
if not enable_promote:
|
|
1090
|
+
return promote_mod.PromoteRefusal(
|
|
1091
|
+
"promotion disabled; pass --enable-promote")
|
|
1092
|
+
|
|
1093
|
+
qdb = quarantine_db_path(self.storage)
|
|
1094
|
+
row = quarantine.get(qdb, rowid)
|
|
1095
|
+
if row is None:
|
|
1096
|
+
return promote_mod.PromoteRefusal(f"no quarantine row #{rowid}")
|
|
1097
|
+
if row.import_status != "quarantined":
|
|
1098
|
+
return promote_mod.PromoteRefusal(
|
|
1099
|
+
f"row #{rowid} is not quarantined "
|
|
1100
|
+
f"(status={row.import_status})")
|
|
1101
|
+
if row.promoted_ts > 0:
|
|
1102
|
+
return promote_mod.PromoteRefusal(
|
|
1103
|
+
f"row #{rowid} already promoted "
|
|
1104
|
+
f"(skill #{row.promoted_skill_id})")
|
|
1105
|
+
if artifact.content_hash(row.artifact_json) != row.content_sha256:
|
|
1106
|
+
return promote_mod.PromoteRefusal(
|
|
1107
|
+
f"row #{rowid} tampered (content_sha256 mismatch)")
|
|
1108
|
+
|
|
1109
|
+
# Live tool registry, real backends. Used ONLY for registry.get(tool)
|
|
1110
|
+
# existence checks — nothing is dispatched, so no tmpdir is needed (the
|
|
1111
|
+
# one structural difference from trial). make_default_registry mkdirs
|
|
1112
|
+
# sandbox_root, so it points inside the instance storage (never real
|
|
1113
|
+
# home), keeping promotion and its tests side-effect-clean.
|
|
1114
|
+
reg = make_default_registry(
|
|
1115
|
+
sandbox_root=self.storage / "sandbox",
|
|
1116
|
+
content_store=self.content_store, event_bus=self.event_bus,
|
|
1117
|
+
goal_generator=self.goals)
|
|
1118
|
+
decision = promote_mod.evaluate_promotion(
|
|
1119
|
+
trial_successes=row.trial_successes,
|
|
1120
|
+
trial_failures=row.trial_failures,
|
|
1121
|
+
tool_seq=row.tool_seq, registry=reg)
|
|
1122
|
+
if not decision.ok:
|
|
1123
|
+
return promote_mod.PromoteRefusal(decision.reason)
|
|
1124
|
+
|
|
1125
|
+
lib = SkillLibrary(self.storage / "conscio.db")
|
|
1126
|
+
try:
|
|
1127
|
+
sid = lib.graft(row.goal_fp, row.goal_text, row.tool_seq,
|
|
1128
|
+
row.plan_template, successes=row.trial_successes,
|
|
1129
|
+
failures=row.trial_failures)
|
|
1130
|
+
finally:
|
|
1131
|
+
lib.close()
|
|
1132
|
+
if sid is None:
|
|
1133
|
+
return promote_mod.PromoteRefusal(
|
|
1134
|
+
"skill already present (goal_fp, tool_seq collision)")
|
|
1135
|
+
|
|
1136
|
+
quarantine.mark_promoted(qdb, rowid, ts=time.time(), skill_id=sid)
|
|
1137
|
+
return promote_mod.PromoteResult(sid, row.trial_successes,
|
|
1138
|
+
row.trial_failures)
|
|
1139
|
+
|
|
1067
1140
|
# --- v2.0 "Connect": propose-only cognition (never executes) ---
|
|
1068
1141
|
|
|
1069
1142
|
def propose_action(self, intent: dict) -> dict:
|
|
@@ -33,6 +33,8 @@ CREATE TABLE IF NOT EXISTS quarantine (
|
|
|
33
33
|
last_trial_ts REAL NOT NULL DEFAULT 0,
|
|
34
34
|
last_trial_result TEXT NOT NULL DEFAULT '',
|
|
35
35
|
last_trial_error TEXT NOT NULL DEFAULT '',
|
|
36
|
+
promoted_ts REAL NOT NULL DEFAULT 0,
|
|
37
|
+
promoted_skill_id INTEGER NOT NULL DEFAULT 0,
|
|
36
38
|
UNIQUE(origin_instance_id, content_sha256)
|
|
37
39
|
);
|
|
38
40
|
"""
|
|
@@ -46,12 +48,18 @@ _TRIAL_COLS = {
|
|
|
46
48
|
"last_trial_error": "TEXT NOT NULL DEFAULT ''",
|
|
47
49
|
}
|
|
48
50
|
|
|
51
|
+
# v2.3: promotion-stats columns added to pre-existing DBs via _migrate.
|
|
52
|
+
_PROMOTE_COLS = {
|
|
53
|
+
"promoted_ts": "REAL NOT NULL DEFAULT 0",
|
|
54
|
+
"promoted_skill_id": "INTEGER NOT NULL DEFAULT 0",
|
|
55
|
+
}
|
|
56
|
+
|
|
49
57
|
|
|
50
58
|
def _migrate(conn: sqlite3.Connection) -> None:
|
|
51
|
-
"""Idempotent ADD COLUMN for pre-v2.2.2 DBs. SQLite has no ADD COLUMN
|
|
52
|
-
NOT EXISTS, so guard with PRAGMA table_info."""
|
|
59
|
+
"""Idempotent ADD COLUMN for pre-v2.2.2/v2.3 DBs. SQLite has no ADD COLUMN
|
|
60
|
+
IF NOT EXISTS, so guard with PRAGMA table_info."""
|
|
53
61
|
have = {r["name"] for r in conn.execute("PRAGMA table_info(quarantine)")}
|
|
54
|
-
for col, decl in _TRIAL_COLS.items():
|
|
62
|
+
for col, decl in {**_TRIAL_COLS, **_PROMOTE_COLS}.items():
|
|
55
63
|
if col not in have:
|
|
56
64
|
conn.execute(f"ALTER TABLE quarantine ADD COLUMN {col} {decl}")
|
|
57
65
|
|
|
@@ -78,6 +86,8 @@ class QuarantineRow:
|
|
|
78
86
|
last_trial_ts: float = 0.0
|
|
79
87
|
last_trial_result: str = ""
|
|
80
88
|
last_trial_error: str = ""
|
|
89
|
+
promoted_ts: float = 0.0
|
|
90
|
+
promoted_skill_id: int = 0
|
|
81
91
|
id: int | None = None
|
|
82
92
|
|
|
83
93
|
|
|
@@ -116,7 +126,8 @@ def _row(r: sqlite3.Row) -> QuarantineRow:
|
|
|
116
126
|
revalidation_error=r["revalidation_error"], schema_version=r["schema_version"],
|
|
117
127
|
trial_successes=r["trial_successes"], trial_failures=r["trial_failures"],
|
|
118
128
|
last_trial_ts=r["last_trial_ts"], last_trial_result=r["last_trial_result"],
|
|
119
|
-
last_trial_error=r["last_trial_error"]
|
|
129
|
+
last_trial_error=r["last_trial_error"],
|
|
130
|
+
promoted_ts=r["promoted_ts"], promoted_skill_id=r["promoted_skill_id"])
|
|
120
131
|
|
|
121
132
|
|
|
122
133
|
def insert(db: Path, row: QuarantineRow) -> bool:
|
|
@@ -196,3 +207,18 @@ def note_trial(db: Path, rowid: int, *, result: str, error: str,
|
|
|
196
207
|
return cur.rowcount > 0
|
|
197
208
|
finally:
|
|
198
209
|
conn.close()
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def mark_promoted(db: Path, rowid: int, *, ts: float, skill_id: int) -> bool:
|
|
213
|
+
"""Stamp promoted_ts / promoted_skill_id after a successful graft into the
|
|
214
|
+
live library. Returns True iff a row was updated. Never touches the trial
|
|
215
|
+
counters or import_status."""
|
|
216
|
+
conn = _connect(db)
|
|
217
|
+
try:
|
|
218
|
+
cur = conn.execute(
|
|
219
|
+
"UPDATE quarantine SET promoted_ts = ?, promoted_skill_id = ?"
|
|
220
|
+
" WHERE id = ?", (ts, skill_id, rowid))
|
|
221
|
+
conn.commit()
|
|
222
|
+
return cur.rowcount > 0
|
|
223
|
+
finally:
|
|
224
|
+
conn.close()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: conscio
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Self-awareness framework for AI agents — emergent consciousness via context-aware memory, introspection, and goal generation
|
|
5
5
|
Author-email: Neguiolidas <neguitech@proton.me>
|
|
6
6
|
License: MIT
|
|
@@ -46,8 +46,9 @@ nothing else). It is designed to make small, local models punch far above their
|
|
|
46
46
|
size by giving them memory, self-judgment, and procedural skill — and to prove
|
|
47
47
|
that claim by measurement, not assertion.
|
|
48
48
|
|
|
49
|
-
- **Current release:** `v2.
|
|
50
|
-
- **Prior:** `v2.2.
|
|
49
|
+
- **Current release:** `v2.3.0` — "Promotion": a quarantined skill that has earned **≥ 3 clean local trials** can now be **graduated into the live skill library**. `conscio promote --quarantine ROWID --enable-promote` re-checks the content hash, verifies every tool in the plan exists locally (**tool-existence check**), and grafts the skill seeded with the counters it earned in the sandbox — **never the origin's stats**, so no trust is inherited. Engine-side write; the noosphere stays engine-free and read-only on `conscio.db`. Never overwrites a local skill; idempotent; off by default and independent of `--enable-trial`/`--enable-act`. `pip install conscio`.
|
|
50
|
+
- **Prior:** `v2.2.2` — "Trial / execution path": a quarantined imported skill can **prove itself locally** before promotion — `conscio trial --quarantine ROWID --enable-trial` replays the fixed foreign plan in a **throwaway, fs-only sandbox** through the full safety stack (`validate → precheck → HIGH-block → Skeptic → dispatch`), recording a binary pass/fail on the quarantine row. Fully **isolated** — never writes the live agent's ledger/skills/trust/breaker; tamper refuses without counting. Off by default; independent of `--enable-act`.
|
|
51
|
+
- **Earlier:** `v2.2.1` — "Mutual audit": an instance publishes a non-sensitive projection of its action ledger (`conscio noosphere publish-record`) to the host-shared `noosphere.db`, and a peer **independently audits** it (`conscio noosphere audit`) — deterministic, read-only, engine-free. The auditor re-derives track-record, breaker quarantines, and a foreign-trust level under its **own** thresholds (parity-tested against the engine) and runs a discipline check (did the peer execute actions its own Skeptic FAILed?). No inherited trust; report-only; the auditor persists nothing.
|
|
51
52
|
- **Earlier:** `v2.2.0` — "Society" (Noosphere Core): same-host Conscio instances **share locally-proven skills as data**. `conscio noosphere publish` copies your proven skills (stats stripped) into a host-shared `noosphere.db`; `conscio noosphere import` pulls another instance's skills into a local **quarantine** after execution-free static revalidation. Engine-free; opens your live `conscio.db` **read-only**; zero network/socket. Nothing imported is trusted, served, executed, or promoted — trust is never inherited.
|
|
52
53
|
- **Earlier:** `v2.1.0` — "Hub": a **localhost stdlib HTTP control plane** (`conscio-hub`) to swap the active model/provider and register custom OpenAI-compatible providers without hand-editing JSON. Engine-free; config applies on next boot. Per-provider model auto-discovery; one-shot smoke test before save. `api_key_env` resolution (env var name → value at adapter build time) is now additive to raw `api_key` — daemon + MCP inherit it. Hub never returns a raw API key.
|
|
53
54
|
- **Earlier:** `v2.0.1` — "Connect" continued: **opt-in, host-executed audited `act` over MCP**. Conscio audits + gates + ledgers an action and returns an *execution packet*; the **host** executes and reports the outcome back — Conscio still never touches the world. Off by default (`conscio-mcp --enable-act`, requires the engine **Awake**); the host declares its tool manifest (`name`/`params`/`risk`/`approval_policy`) in `initialize`; HIGH-risk / `require_approval` actions stay **queued for human/Hermes approval** (`conscio.pending` → `conscio.approve`). Also: `conscio-mcp` adapter parity (six providers from config) and the **R-05** content-store dedup fix — shipping **debt-zero**. Cognition (`reflect()`) untouched; purely additive.
|
|
@@ -63,6 +63,7 @@ conscio/agency/host_act.py
|
|
|
63
63
|
conscio/agency/ledger.py
|
|
64
64
|
conscio/agency/loop.py
|
|
65
65
|
conscio/agency/profiles.py
|
|
66
|
+
conscio/agency/promote.py
|
|
66
67
|
conscio/agency/skeptic.py
|
|
67
68
|
conscio/agency/skills.py
|
|
68
69
|
conscio/agency/tools.py
|
|
@@ -121,6 +122,7 @@ tests/test_agency_ledger_v201.py
|
|
|
121
122
|
tests/test_agency_loop.py
|
|
122
123
|
tests/test_agency_no_network.py
|
|
123
124
|
tests/test_agency_profiles.py
|
|
125
|
+
tests/test_agency_promote.py
|
|
124
126
|
tests/test_agency_skeptic.py
|
|
125
127
|
tests/test_agency_skills.py
|
|
126
128
|
tests/test_agency_skills_wiring.py
|
|
@@ -136,6 +138,7 @@ tests/test_awake.py
|
|
|
136
138
|
tests/test_axis_pack.py
|
|
137
139
|
tests/test_axis_pack_battery.py
|
|
138
140
|
tests/test_cli.py
|
|
141
|
+
tests/test_cli_promote.py
|
|
139
142
|
tests/test_cli_trial.py
|
|
140
143
|
tests/test_coherence.py
|
|
141
144
|
tests/test_coherence_engine_integration.py
|
|
@@ -163,6 +166,7 @@ tests/test_engine_advisory.py
|
|
|
163
166
|
tests/test_engine_host_act.py
|
|
164
167
|
tests/test_engine_init.py
|
|
165
168
|
tests/test_engine_meta_reflect.py
|
|
169
|
+
tests/test_engine_promote.py
|
|
166
170
|
tests/test_engine_propose.py
|
|
167
171
|
tests/test_engine_recall.py
|
|
168
172
|
tests/test_engine_trial.py
|
|
@@ -216,6 +220,7 @@ tests/test_packaging.py
|
|
|
216
220
|
tests/test_perception.py
|
|
217
221
|
tests/test_perf_reflection.py
|
|
218
222
|
tests/test_plugins.py
|
|
223
|
+
tests/test_quarantine_promote.py
|
|
219
224
|
tests/test_quarantine_trial.py
|
|
220
225
|
tests/test_recursive_loop_integration.py
|
|
221
226
|
tests/test_risk.py
|
|
@@ -229,6 +234,7 @@ tests/test_session_lifecycle_battery.py
|
|
|
229
234
|
tests/test_session_lifecycle_dream.py
|
|
230
235
|
tests/test_session_rag.py
|
|
231
236
|
tests/test_shard_engine.py
|
|
237
|
+
tests/test_skills_graft.py
|
|
232
238
|
tests/test_state_loaders_battery.py
|
|
233
239
|
tests/test_state_persistence_battery.py
|
|
234
240
|
tests/test_structural.py
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# tests/test_agency_promote.py
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from conscio.agency.promote import (MIN_PROMOTE_PASSES, PromoteDecision,
|
|
5
|
+
evaluate_promotion)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class _Reg:
|
|
9
|
+
"""Minimal registry stub: a tool exists iff its name is in `known`."""
|
|
10
|
+
def __init__(self, known):
|
|
11
|
+
self.known = set(known)
|
|
12
|
+
|
|
13
|
+
def get(self, name):
|
|
14
|
+
return object() if name in self.known else None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _seq(*tools):
|
|
18
|
+
return json.dumps(list(tools))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_enough_clean_passes_ok():
|
|
22
|
+
d = evaluate_promotion(trial_successes=3, trial_failures=0,
|
|
23
|
+
tool_seq=_seq("fs_read"), registry=_Reg(["fs_read"]))
|
|
24
|
+
assert d == PromoteDecision(True, "")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_boundary_three_passes_ok():
|
|
28
|
+
assert MIN_PROMOTE_PASSES == 3
|
|
29
|
+
d = evaluate_promotion(trial_successes=3, trial_failures=0,
|
|
30
|
+
tool_seq=_seq("fs_read"), registry=_Reg(["fs_read"]))
|
|
31
|
+
assert d.ok
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_insufficient_passes_refused():
|
|
35
|
+
d = evaluate_promotion(trial_successes=2, trial_failures=0,
|
|
36
|
+
tool_seq=_seq("fs_read"), registry=_Reg(["fs_read"]))
|
|
37
|
+
assert not d.ok and "insufficient" in d.reason
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_any_failure_refused():
|
|
41
|
+
d = evaluate_promotion(trial_successes=9, trial_failures=1,
|
|
42
|
+
tool_seq=_seq("fs_read"), registry=_Reg(["fs_read"]))
|
|
43
|
+
assert not d.ok and "failed" in d.reason
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_unknown_tool_refused():
|
|
47
|
+
d = evaluate_promotion(trial_successes=5, trial_failures=0,
|
|
48
|
+
tool_seq=_seq("fs_read", "rm_rf"),
|
|
49
|
+
registry=_Reg(["fs_read"]))
|
|
50
|
+
assert not d.ok and "rm_rf" in d.reason
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_corrupt_tool_seq_refused():
|
|
54
|
+
d = evaluate_promotion(trial_successes=5, trial_failures=0,
|
|
55
|
+
tool_seq='{"not":"a list"}', registry=_Reg([]))
|
|
56
|
+
assert not d.ok and "corrupt tool_seq" in d.reason
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# tests/test_cli_promote.py
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
from conscio import cli
|
|
5
|
+
from conscio.agency.promote import PromoteRefusal, PromoteResult
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_promote_rc0_on_result(monkeypatch, capsys):
|
|
9
|
+
monkeypatch.setattr(cli, "_run_promote",
|
|
10
|
+
lambda **kw: PromoteResult(7, 3, 0))
|
|
11
|
+
rc = cli.main(["promote", "--quarantine", "1", "--enable-promote"])
|
|
12
|
+
assert rc == 0
|
|
13
|
+
assert "PROMOTED skill #7" in capsys.readouterr().out
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_promote_rc1_on_refusal(monkeypatch, capsys):
|
|
17
|
+
monkeypatch.setattr(cli, "_run_promote",
|
|
18
|
+
lambda **kw: PromoteRefusal("nope"))
|
|
19
|
+
rc = cli.main(["promote", "--quarantine", "1", "--enable-promote"])
|
|
20
|
+
assert rc == 1
|
|
21
|
+
assert "PROMOTE REFUSED: nope" in capsys.readouterr().out
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_promote_rc1_on_exception(monkeypatch, capsys):
|
|
25
|
+
def boom(**kw):
|
|
26
|
+
raise RuntimeError("wiring failed")
|
|
27
|
+
monkeypatch.setattr(cli, "_run_promote", boom)
|
|
28
|
+
rc = cli.main(["promote", "--quarantine", "1", "--enable-promote"])
|
|
29
|
+
assert rc == 1
|
|
30
|
+
assert "error: wiring failed" in capsys.readouterr().out
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_promote_requires_quarantine():
|
|
34
|
+
with pytest.raises(SystemExit):
|
|
35
|
+
cli.main(["promote", "--enable-promote"])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_promote_disabled_by_default(monkeypatch):
|
|
39
|
+
seen = {}
|
|
40
|
+
monkeypatch.setattr(
|
|
41
|
+
cli, "_run_promote",
|
|
42
|
+
lambda **kw: seen.update(kw) or PromoteRefusal("x"))
|
|
43
|
+
cli.main(["promote", "--quarantine", "5"])
|
|
44
|
+
assert seen["enable_promote"] is False
|
|
45
|
+
assert seen["quarantine_id"] == 5
|