apsimo 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apsimo/__init__.py +38 -0
- apsimo/__main__.py +6 -0
- apsimo/agent/__init__.py +6 -0
- apsimo/agent/client.py +276 -0
- apsimo/agent/models.py +46 -0
- apsimo/agents/__init__.py +20 -0
- apsimo/agents/models.py +264 -0
- apsimo/agents/store.py +861 -0
- apsimo/agents/websocket.py +522 -0
- apsimo/api/__init__.py +1 -0
- apsimo/api/auth_telemetry.py +287 -0
- apsimo/api/authority.py +1203 -0
- apsimo/api/contact_grants.py +347 -0
- apsimo/api/middleware.py +483 -0
- apsimo/api/routers/__init__.py +1 -0
- apsimo/api/routers/commitment_work.py +265 -0
- apsimo/api/routers/context_gate.py +123 -0
- apsimo/api/routers/executions.py +140 -0
- apsimo/api/routers/followup_plans.py +147 -0
- apsimo/api/routers/governed_actions.py +162 -0
- apsimo/api/routers/host.py +14473 -0
- apsimo/api/routers/initiative_work.py +115 -0
- apsimo/api/routers/mining.py +104 -0
- apsimo/api/routers/observations.py +110 -0
- apsimo/api/routers/social_state.py +225 -0
- apsimo/api/routers/task_queue.py +2715 -0
- apsimo/api/routers/temporal_followups.py +251 -0
- apsimo/api/routers/transport.py +110 -0
- apsimo/api/routers/transport_ingress_api.py +240 -0
- apsimo/api/schemas/__init__.py +1 -0
- apsimo/api/schemas/host.py +1949 -0
- apsimo/autonomy/cli.py +110 -0
- apsimo/autonomy/condition_worker.py +437 -0
- apsimo/autonomy/config.py +424 -0
- apsimo/autonomy/loop.py +4316 -0
- apsimo/autonomy/registry.py +339 -0
- apsimo/autonomy/scheduler.py +1822 -0
- apsimo/autonomy/synthesis.py +449 -0
- apsimo/backup.py +962 -0
- apsimo/beliefs/__init__.py +23 -0
- apsimo/beliefs/contradictions.py +109 -0
- apsimo/beliefs/decay.py +61 -0
- apsimo/beliefs/engine.py +479 -0
- apsimo/beliefs/models.py +67 -0
- apsimo/beliefs/promotion.py +41 -0
- apsimo/beliefs/resolve.py +58 -0
- apsimo/beliefs/source_claims.py +690 -0
- apsimo/beliefs/source_projection.py +883 -0
- apsimo/beliefs/source_time.py +208 -0
- apsimo/beliefs/store.py +133 -0
- apsimo/briefings/aggregators.py +824 -0
- apsimo/briefings/composer.py +420 -0
- apsimo/briefings/config.py +55 -0
- apsimo/briefings/delivery.py +439 -0
- apsimo/briefings/engagement.py +97 -0
- apsimo/briefings/engine.py +274 -0
- apsimo/briefings/enhancer.py +99 -0
- apsimo/briefings/models.py +183 -0
- apsimo/briefings/scheduler.py +382 -0
- apsimo/briefings/store.py +435 -0
- apsimo/chain/__init__.py +48 -0
- apsimo/chain/block.py +100 -0
- apsimo/chain/cli.py +704 -0
- apsimo/chain/genesis.py +443 -0
- apsimo/chain/identity.py +416 -0
- apsimo/chain/keys.py +1025 -0
- apsimo/chain/local_keys.py +187 -0
- apsimo/chain/manager.py +290 -0
- apsimo/chain/node.py +163 -0
- apsimo/chain/plugin_transactions.py +371 -0
- apsimo/chain/protocol.py +220 -0
- apsimo/chain/state_machine.py +676 -0
- apsimo/chain/storage.py +503 -0
- apsimo/chain/transactions.py +250 -0
- apsimo/chain/validation.py +397 -0
- apsimo/channels/__init__.py +1 -0
- apsimo/channels/manifest.py +31 -0
- apsimo/channels/migrations/001_channels_schema.sql +12 -0
- apsimo/channels/phone_gateways.py +42 -0
- apsimo/channels/presence.py +188 -0
- apsimo/channels/router.py +235 -0
- apsimo/channels/store.py +231 -0
- apsimo/cli.py +2688 -0
- apsimo/cognition/__init__.py +11 -0
- apsimo/cognition/charter.py +398 -0
- apsimo/cognition/drive_governance.py +3530 -0
- apsimo/cognition/evidence_pipeline.py +1627 -0
- apsimo/cognition/external_events.py +932 -0
- apsimo/cognition/goal_spine.py +3488 -0
- apsimo/cognition/introspection.py +214 -0
- apsimo/cognition/prompt.py +150 -0
- apsimo/cognition/runtime.py +108 -0
- apsimo/cognition/trigger.py +154 -0
- apsimo/commitments/__init__.py +18 -0
- apsimo/commitments/local_work.py +355 -0
- apsimo/commitments/store.py +1052 -0
- apsimo/commitments/work.py +91 -0
- apsimo/compat.py +53 -0
- apsimo/compression/__init__.py +467 -0
- apsimo/connectors/__init__.py +21 -0
- apsimo/connectors/base.py +152 -0
- apsimo/connectors/caldav_calendar.py +125 -0
- apsimo/connectors/fs_documents.py +85 -0
- apsimo/connectors/imap_email.py +138 -0
- apsimo/connectors/manager.py +218 -0
- apsimo/connectors/webhook_pull.py +88 -0
- apsimo/contacts/__init__.py +33 -0
- apsimo/contacts/comms.py +357 -0
- apsimo/contacts/config.py +79 -0
- apsimo/contacts/exporters/__init__.py +1 -0
- apsimo/contacts/exporters/vcard.py +71 -0
- apsimo/contacts/identity_links.py +251 -0
- apsimo/contacts/importer.py +280 -0
- apsimo/contacts/importers/__init__.py +1 -0
- apsimo/contacts/importers/batch.py +43 -0
- apsimo/contacts/importers/macos_contacts.py +101 -0
- apsimo/contacts/migrations/001_contacts_schema.sql +141 -0
- apsimo/contacts/migrations/002_trust_scopes.sql +36 -0
- apsimo/contacts/migrations/003_open_gateway_enum.sql +32 -0
- apsimo/contacts/migrations/004_contact_provision_operations.sql +18 -0
- apsimo/contacts/migrations/005_identity_links.sql +27 -0
- apsimo/contacts/models.py +308 -0
- apsimo/contacts/scoring.py +16 -0
- apsimo/contacts/store.py +1623 -0
- apsimo/contacts/transport_ingress.py +252 -0
- apsimo/contacts/world_bridge.py +314 -0
- apsimo/contextgate/__init__.py +69 -0
- apsimo/contextgate/chunker.py +169 -0
- apsimo/contextgate/estimate.py +54 -0
- apsimo/contextgate/gate.py +313 -0
- apsimo/contextgate/retrieve.py +115 -0
- apsimo/delivery/__init__.py +16 -0
- apsimo/delivery/bridge.py +1260 -0
- apsimo/delivery/channels.py +526 -0
- apsimo/delivery/classification.py +50 -0
- apsimo/delivery/rate_limiter.py +268 -0
- apsimo/delivery/reachout_policy.py +206 -0
- apsimo/directed/__init__.py +22 -0
- apsimo/directed/audit.py +167 -0
- apsimo/directed/intake.py +95 -0
- apsimo/directed/models.py +191 -0
- apsimo/directed/service.py +509 -0
- apsimo/directives/__init__.py +25 -0
- apsimo/directives/evidence.py +87 -0
- apsimo/directives/extractor.py +188 -0
- apsimo/directives/guard.py +364 -0
- apsimo/directives/models.py +206 -0
- apsimo/directives/service.py +372 -0
- apsimo/directives/store.py +167 -0
- apsimo/doctor.py +2173 -0
- apsimo/environment.py +43 -0
- apsimo/events/__init__.py +33 -0
- apsimo/events/broadcaster.py +98 -0
- apsimo/events/bus.py +217 -0
- apsimo/events/journal.py +863 -0
- apsimo/events/stream.py +131 -0
- apsimo/events/types.py +150 -0
- apsimo/execution_results.py +357 -0
- apsimo/feedback/__init__.py +5 -0
- apsimo/feedback/store.py +76 -0
- apsimo/feeds/__init__.py +19 -0
- apsimo/feeds/cli.py +84 -0
- apsimo/feeds/engine.py +437 -0
- apsimo/feeds/example-feed.yaml +77 -0
- apsimo/feeds/hermes_cron.py +126 -0
- apsimo/feeds/manager.py +235 -0
- apsimo/feeds/spec.py +250 -0
- apsimo/feeds/template.py +202 -0
- apsimo/gate/__init__.py +18 -0
- apsimo/gate/audit.py +61 -0
- apsimo/gate/communication_policy.py +166 -0
- apsimo/gate/config.py +72 -0
- apsimo/gate/context_provenance.py +170 -0
- apsimo/gate/env_risk.py +226 -0
- apsimo/gate/guard_audit.py +353 -0
- apsimo/gate/layers/__init__.py +1 -0
- apsimo/gate/layers/base.py +15 -0
- apsimo/gate/layers/l1_recipient.py +66 -0
- apsimo/gate/layers/l2_pii.py +134 -0
- apsimo/gate/layers/l3_cross_context.py +50 -0
- apsimo/gate/layers/l4_trust_tier.py +78 -0
- apsimo/gate/layers/l5_injection.py +199 -0
- apsimo/gate/layers/l6_review.py +86 -0
- apsimo/gate/layers/l7_delay.py +100 -0
- apsimo/gate/layers/tom2_epistemic.py +185 -0
- apsimo/gate/models.py +64 -0
- apsimo/gate/pending_dispatch.py +5 -0
- apsimo/gate/pipeline.py +206 -0
- apsimo/gate/rejection.py +259 -0
- apsimo/gate/response_guard.py +700 -0
- apsimo/gate/rulesets/injection_v1.yaml +51 -0
- apsimo/gate/surface_policy.py +189 -0
- apsimo/gate/taint.py +226 -0
- apsimo/genesis.json +9 -0
- apsimo/goals/__init__.py +100 -0
- apsimo/goals/config.py +38 -0
- apsimo/goals/decomposer.py +421 -0
- apsimo/goals/engine.py +617 -0
- apsimo/goals/inference.py +354 -0
- apsimo/goals/models.py +302 -0
- apsimo/goals/priority.py +270 -0
- apsimo/goals/queue_bridge.py +149 -0
- apsimo/goals/replan.py +450 -0
- apsimo/goals/schema.sql +89 -0
- apsimo/goals/store.py +692 -0
- apsimo/governed_actions.py +1708 -0
- apsimo/harness_integration/__init__.py +45 -0
- apsimo/harness_integration/context.py +41 -0
- apsimo/harness_integration/skills.py +231 -0
- apsimo/identity/__init__.py +26 -0
- apsimo/identity/participants.py +181 -0
- apsimo/identity/resolver.py +329 -0
- apsimo/identity_bootstrap/__init__.py +5 -0
- apsimo/identity_bootstrap/builder.py +208 -0
- apsimo/identity_bootstrap/corpus.py +443 -0
- apsimo/identity_bootstrap/models.py +54 -0
- apsimo/identity_bootstrap/runner.py +353 -0
- apsimo/identity_bootstrap/seeders/__init__.py +25 -0
- apsimo/identity_bootstrap/seeders/briefings.py +109 -0
- apsimo/identity_bootstrap/seeders/chain.py +57 -0
- apsimo/identity_bootstrap/seeders/goals.py +128 -0
- apsimo/identity_bootstrap/seeders/memory.py +191 -0
- apsimo/identity_bootstrap/seeders/neo4j_cognition.py +79 -0
- apsimo/identity_bootstrap/seeders/relationship.py +152 -0
- apsimo/identity_bootstrap/seeders/sessions.py +67 -0
- apsimo/identity_bootstrap/seeders/skills.py +92 -0
- apsimo/identity_bootstrap/seeders/task_queue.py +72 -0
- apsimo/identity_bootstrap/seeders/world_model.py +143 -0
- apsimo/identity_bootstrap/self_query.py +92 -0
- apsimo/identity_bootstrap/self_reflection.py +155 -0
- apsimo/identity_bootstrap/skill.py +37 -0
- apsimo/identity_bootstrap/verifier.py +436 -0
- apsimo/initiatives/__init__.py +20 -0
- apsimo/initiatives/action_registry.py +454 -0
- apsimo/initiatives/approval_authority.py +2105 -0
- apsimo/initiatives/approval_policy.py +123 -0
- apsimo/initiatives/assignment.py +263 -0
- apsimo/initiatives/backup_evidence.py +100 -0
- apsimo/initiatives/context_freshness.py +103 -0
- apsimo/initiatives/models.py +318 -0
- apsimo/initiatives/native_work.py +270 -0
- apsimo/initiatives/standing_approvals.py +232 -0
- apsimo/initiatives/store.py +1081 -0
- apsimo/initiatives/temporal_followup.py +410 -0
- apsimo/intelligence/__init__.py +1 -0
- apsimo/intelligence/cognition/__init__.py +24 -0
- apsimo/intelligence/cognition/gap_detector.py +148 -0
- apsimo/intelligence/cognition/metalearner.py +547 -0
- apsimo/intelligence/cognition/metrics_collector.py +217 -0
- apsimo/intelligence/cognition/performance_index.py +299 -0
- apsimo/intelligence/cognition/registry.py +192 -0
- apsimo/intelligence/cognition/strategy_adjuster.py +222 -0
- apsimo/intelligence/cognition/types.py +16 -0
- apsimo/intelligence/components/__init__.py +66 -0
- apsimo/intelligence/components/anomaly_detector.py +413 -0
- apsimo/intelligence/components/initiative_engine.py +2643 -0
- apsimo/intelligence/components/preference_learner.py +521 -0
- apsimo/intelligence/components/research_orchestrator.py +358 -0
- apsimo/intelligence/components/self_directed_thinker.py +221 -0
- apsimo/intelligence/components/self_reflector.py +252 -0
- apsimo/intelligence/components/session_continuity.py +154 -0
- apsimo/intelligence/components/task_planner.py +320 -0
- apsimo/intelligence/components/tool_learner.py +217 -0
- apsimo/intelligence/graph/__init__.py +79 -0
- apsimo/intelligence/graph/client.py +2483 -0
- apsimo/intelligence/graph/consolidator.py +405 -0
- apsimo/intelligence/graph/distiller.py +312 -0
- apsimo/intelligence/graph/migrations.py +129 -0
- apsimo/intelligence/graph/queries.py +248 -0
- apsimo/intelligence/graph/recall.py +281 -0
- apsimo/intelligence/graph/reconciler.py +144 -0
- apsimo/intelligence/graph/schema.py +337 -0
- apsimo/intelligence/graph/selection.py +252 -0
- apsimo/intelligence/learning/__init__.py +17 -0
- apsimo/intelligence/learning/continuous_learner.py +245 -0
- apsimo/intelligence/learning/feedback_store.py +321 -0
- apsimo/intelligence/mind_model/__init__.py +1 -0
- apsimo/intelligence/mind_model/graph_baseline.py +136 -0
- apsimo/intelligence/mind_model/signal_collector.py +361 -0
- apsimo/intelligence/relationships/__init__.py +11 -0
- apsimo/intelligence/relationships/profiler.py +389 -0
- apsimo/intelligence/relationships/scorer.py +560 -0
- apsimo/intelligence/relationships/signal_floor.py +66 -0
- apsimo/intelligence/relationships/trust_tiers.py +300 -0
- apsimo/intelligence/synthesis/__init__.py +40 -0
- apsimo/intelligence/synthesis/connection_discoverer.py +379 -0
- apsimo/intelligence/synthesis/cross_domain_analyzer.py +287 -0
- apsimo/intelligence/synthesis/insight_deliverer.py +171 -0
- apsimo/intelligence/synthesis/insight_store.py +79 -0
- apsimo/intelligence/synthesis/insight_validator.py +183 -0
- apsimo/intelligence/synthesis/novelty_scorer.py +267 -0
- apsimo/intelligence/turn_middleware/__init__.py +15 -0
- apsimo/intelligence/turn_middleware/memory_sync.py +119 -0
- apsimo/mcp/__init__.py +41 -0
- apsimo/mcp/__main__.py +6 -0
- apsimo/mcp/config.py +287 -0
- apsimo/mcp/server.py +501 -0
- apsimo/migrations.py +187 -0
- apsimo/mining/__init__.py +27 -0
- apsimo/mining/corpus.py +239 -0
- apsimo/mining/escalations.py +289 -0
- apsimo/mining/models.py +169 -0
- apsimo/mining/store.py +210 -0
- apsimo/models/__init__.py +30 -0
- apsimo/models/memory.py +80 -0
- apsimo/models/mesh.py +72 -0
- apsimo/models/person.py +104 -0
- apsimo/models/signal.py +108 -0
- apsimo/observations/__init__.py +15 -0
- apsimo/observations/store.py +277 -0
- apsimo/patterns/__init__.py +6 -0
- apsimo/patterns/extract.py +187 -0
- apsimo/patterns/store.py +227 -0
- apsimo/persona/__init__.py +1 -0
- apsimo/persona/engine.py +611 -0
- apsimo/persona/manifest.py +140 -0
- apsimo/projects/__init__.py +28 -0
- apsimo/projects/engine.py +1681 -0
- apsimo/projects/event_outbox.py +188 -0
- apsimo/projects/models.py +216 -0
- apsimo/projects/planner.py +181 -0
- apsimo/projects/store.py +1446 -0
- apsimo/proposals/__init__.py +12 -0
- apsimo/proposals/engine.py +114 -0
- apsimo/proposals/models.py +207 -0
- apsimo/qualification/__init__.py +1 -0
- apsimo/qualification/cases.py +75 -0
- apsimo/qualification/cli.py +51 -0
- apsimo/qualification/memory_cases.py +209 -0
- apsimo/qualification/records.py +92 -0
- apsimo/qualification/report.py +87 -0
- apsimo/qualification/runner.py +311 -0
- apsimo/qualification/structured_cases.py +131 -0
- apsimo/reasoning/__init__.py +13 -0
- apsimo/reasoning/executor.py +506 -0
- apsimo/reasoning/loop.py +373 -0
- apsimo/reasoning/native_tools/__init__.py +16 -0
- apsimo/reasoning/native_tools/calculate.py +141 -0
- apsimo/reasoning/native_tools/file_ops.py +150 -0
- apsimo/reasoning/native_tools/web_search.py +49 -0
- apsimo/reasoning/tool_policy.py +182 -0
- apsimo/redact/__init__.py +176 -0
- apsimo/repos/__init__.py +5 -0
- apsimo/repos/mirrors.py +204 -0
- apsimo/research/__init__.py +41 -0
- apsimo/research/artifact.py +482 -0
- apsimo/research/gatherer.py +387 -0
- apsimo/research/pipeline.py +513 -0
- apsimo/research/search/__init__.py +7 -0
- apsimo/research/search/base.py +41 -0
- apsimo/research/search/brave.py +59 -0
- apsimo/research/search/cache.py +51 -0
- apsimo/research/search/duckduckgo.py +103 -0
- apsimo/research/search/orchestrator.py +119 -0
- apsimo/research/search/serpapi.py +59 -0
- apsimo/research/search/tavily.py +59 -0
- apsimo/research/synthesizer.py +309 -0
- apsimo/router/__init__.py +30 -0
- apsimo/router/complexity_scorer.py +148 -0
- apsimo/router/endpoints.py +153 -0
- apsimo/router/fallback.py +58 -0
- apsimo/router/functions.py +243 -0
- apsimo/router/native_policy.py +52 -0
- apsimo/router/router.py +762 -0
- apsimo/router/self_learning.py +174 -0
- apsimo/router/tiers.py +677 -0
- apsimo/sandbox/__init__.py +21 -0
- apsimo/sandbox/backend.py +195 -0
- apsimo/sandbox/manager.py +173 -0
- apsimo/scope_bounds.py +7 -0
- apsimo/secrets/__init__.py +6 -0
- apsimo/secrets/backends/__init__.py +8 -0
- apsimo/secrets/backends/base.py +42 -0
- apsimo/secrets/backends/env.py +110 -0
- apsimo/secrets/backends/keyring.py +72 -0
- apsimo/secrets/backends/onepassword.py +232 -0
- apsimo/secrets/cli.py +191 -0
- apsimo/secrets/manager.py +160 -0
- apsimo/secrets/migration.py +101 -0
- apsimo/secrets/types.py +98 -0
- apsimo/seed.py +41 -0
- apsimo/self_model/__init__.py +37 -0
- apsimo/self_model/appraisals.py +673 -0
- apsimo/self_model/benchmark.py +1314 -0
- apsimo/self_model/brief.py +40 -0
- apsimo/self_model/event_concerns.py +1128 -0
- apsimo/self_model/execution_forecasts.py +353 -0
- apsimo/self_model/expectations.py +1595 -0
- apsimo/self_model/experiments.py +1150 -0
- apsimo/self_model/journal.py +148 -0
- apsimo/self_model/judgments.py +705 -0
- apsimo/self_model/native_outcomes.py +55 -0
- apsimo/self_model/params.py +220 -0
- apsimo/self_model/perspective.py +246 -0
- apsimo/self_model/reconcile.py +183 -0
- apsimo/self_model/reply_forecasts.py +381 -0
- apsimo/self_model/runtime_forecasts.py +296 -0
- apsimo/self_model/runtime_models.py +67 -0
- apsimo/self_model/settlement.py +207 -0
- apsimo/self_model/situation.py +1731 -0
- apsimo/self_model/store.py +883 -0
- apsimo/self_model/supervised.py +137 -0
- apsimo/self_model/thinker.py +99 -0
- apsimo/self_model/trust.py +388 -0
- apsimo/self_model/workspace.py +2388 -0
- apsimo/server.py +4197 -0
- apsimo/services/__init__.py +1 -0
- apsimo/services/agent_bridge.py +474 -0
- apsimo/services/initiative_executor.py +914 -0
- apsimo/services/instance.py +297 -0
- apsimo/sessions/__init__.py +22 -0
- apsimo/sessions/config.py +13 -0
- apsimo/sessions/context_loader.py +88 -0
- apsimo/sessions/federation_session.py +75 -0
- apsimo/sessions/isolated_session.py +98 -0
- apsimo/sessions/reports.py +84 -0
- apsimo/sessions/store.py +148 -0
- apsimo/setup.py +2818 -0
- apsimo/setup_hermes.py +879 -0
- apsimo/setup_local_work.py +218 -0
- apsimo/setup_native_goals.py +134 -0
- apsimo/setup_native_reviews.py +115 -0
- apsimo/skills/__init__.py +10 -0
- apsimo/skills/base.py +108 -0
- apsimo/skills/budget.py +28 -0
- apsimo/skills/executor.py +493 -0
- apsimo/skills/executors/__init__.py +1 -0
- apsimo/skills/executors/behavioral_correction.py +75 -0
- apsimo/skills/executors/capability_gap.py +38 -0
- apsimo/skills/executors/data_quality.py +163 -0
- apsimo/skills/executors/knowledge_acquisition.py +41 -0
- apsimo/skills/executors/operational_hygiene.py +185 -0
- apsimo/skills/executors/subsystem_health.py +169 -0
- apsimo/skills/hermes_export.py +431 -0
- apsimo/skills/index.py +123 -0
- apsimo/skills/learning/__init__.py +21 -0
- apsimo/skills/learning/novelty_detector.py +206 -0
- apsimo/skills/learning/pattern_extractor.py +199 -0
- apsimo/skills/learning/triggers.py +159 -0
- apsimo/skills/loader.py +246 -0
- apsimo/skills/migrations/002_progressive_loading.sql +6 -0
- apsimo/skills/migrations/backfill_triggers.py +20 -0
- apsimo/skills/models.py +202 -0
- apsimo/skills/packager.py +128 -0
- apsimo/skills/protocols.py +70 -0
- apsimo/skills/registry.py +191 -0
- apsimo/skills/runtime.py +58 -0
- apsimo/skills/sandbox_runner.py +229 -0
- apsimo/skills/scheduler.py +129 -0
- apsimo/skills/schema.py +79 -0
- apsimo/skills/security/__init__.py +12 -0
- apsimo/skills/security/guards.py +53 -0
- apsimo/skills/security/scanner.py +223 -0
- apsimo/skills_memory/__init__.py +26 -0
- apsimo/skills_memory/distill.py +159 -0
- apsimo/skills_memory/models.py +85 -0
- apsimo/skills_memory/retrieve.py +62 -0
- apsimo/skills_memory/store.py +172 -0
- apsimo/surprise/__init__.py +6 -0
- apsimo/surprise/accumulation.py +57 -0
- apsimo/surprise/scorer.py +102 -0
- apsimo/surprise/store.py +203 -0
- apsimo/task_queue/__init__.py +69 -0
- apsimo/task_queue/action_receipts.py +148 -0
- apsimo/task_queue/approval_relay_canary.py +108 -0
- apsimo/task_queue/config.py +85 -0
- apsimo/task_queue/contract.py +361 -0
- apsimo/task_queue/events.py +130 -0
- apsimo/task_queue/governor.py +1031 -0
- apsimo/task_queue/handlers/__init__.py +16 -0
- apsimo/task_queue/handlers/base.py +37 -0
- apsimo/task_queue/handlers/inference.py +640 -0
- apsimo/task_queue/handlers/monitoring.py +116 -0
- apsimo/task_queue/handlers/registry.py +75 -0
- apsimo/task_queue/handlers/subtask_handler.py +173 -0
- apsimo/task_queue/handlers/system_maintenance.py +147 -0
- apsimo/task_queue/mesh_integration.py +111 -0
- apsimo/task_queue/models.py +317 -0
- apsimo/task_queue/queue_manager.py +8286 -0
- apsimo/task_queue/routing.py +287 -0
- apsimo/task_queue/scheduler.py +252 -0
- apsimo/task_queue/schema.sql +197 -0
- apsimo/task_queue/work_control.py +342 -0
- apsimo/task_queue/worker.py +993 -0
- apsimo/telemetry.py +145 -0
- apsimo/tom/__init__.py +6 -0
- apsimo/tom/affect.py +387 -0
- apsimo/tom/approvals.py +171 -0
- apsimo/tom/arcs.py +896 -0
- apsimo/tom/asymmetry.py +131 -0
- apsimo/tom/eligibility.py +248 -0
- apsimo/tom/engagement.py +214 -0
- apsimo/tom/exposure.py +214 -0
- apsimo/tom/extractor.py +306 -0
- apsimo/tom/fact_adapters.py +144 -0
- apsimo/tom/facts.py +326 -0
- apsimo/tom/integration.py +592 -0
- apsimo/tom/leveled.py +118 -0
- apsimo/tom/levels.py +247 -0
- apsimo/tom/recipient_audit.py +995 -0
- apsimo/tom/recipient_simulator.py +593 -0
- apsimo/tom/source_lineage.py +93 -0
- apsimo/tom/tom2.py +277 -0
- apsimo/tom/visibility.py +559 -0
- apsimo/tom/visibility_store.py +414 -0
- apsimo/tools/__init__.py +0 -0
- apsimo/tools/definitions.py +740 -0
- apsimo/tools/handlers.py +943 -0
- apsimo/toolsmith/__init__.py +26 -0
- apsimo/toolsmith/authority.py +166 -0
- apsimo/toolsmith/engine.py +559 -0
- apsimo/toolsmith/integrity.py +100 -0
- apsimo/toolsmith/miner.py +145 -0
- apsimo/toolsmith/policy.py +110 -0
- apsimo/toolsmith/registry.py +635 -0
- apsimo/turns/__init__.py +17 -0
- apsimo/turns/audio.py +134 -0
- apsimo/turns/documents.py +235 -0
- apsimo/turns/executions.py +486 -0
- apsimo/turns/hermes_history.py +245 -0
- apsimo/turns/hermes_kanban.py +268 -0
- apsimo/turns/hermes_work.py +96 -0
- apsimo/turns/idempotency.py +752 -0
- apsimo/turns/local_work.py +115 -0
- apsimo/turns/media.py +581 -0
- apsimo/turns/reported_workers.py +196 -0
- apsimo/turns/source_annotations.py +283 -0
- apsimo/turns/source_attribution.py +154 -0
- apsimo/turns/source_read.py +351 -0
- apsimo/turns/source_vectors.py +263 -0
- apsimo/turns/video.py +210 -0
- apsimo/util/autonomy_preset.py +220 -0
- apsimo/util/instance.py +92 -0
- apsimo/util/model_output.py +25 -0
- apsimo/util/quiet_hours.py +27 -0
- apsimo/util/session_safety.py +37 -0
- apsimo/util/temporal.py +343 -0
- apsimo/vector/__init__.py +75 -0
- apsimo/vector/backfill.py +171 -0
- apsimo/vector/caption.py +114 -0
- apsimo/vector/collections.py +51 -0
- apsimo/vector/config.py +102 -0
- apsimo/vector/embedder.py +670 -0
- apsimo/vector/image_preprocess.py +406 -0
- apsimo/vector/image_store.py +296 -0
- apsimo/vector/indexes.py +162 -0
- apsimo/vector/migrate.py +334 -0
- apsimo/vector/multimodal_provider.py +417 -0
- apsimo/vector/multimodal_types.py +87 -0
- apsimo/vector/openai_provider.py +119 -0
- apsimo/vector/query.py +49 -0
- apsimo/vector/reranker.py +565 -0
- apsimo/vector/safety_image.py +159 -0
- apsimo/vector/scanner.py +197 -0
- apsimo/vector/setup.py +289 -0
- apsimo/vector/store.py +533 -0
- apsimo/vector/tiers.py +263 -0
- apsimo/work_orders.py +925 -0
- apsimo/workers/__init__.py +21 -0
- apsimo/workers/agent_bridge.py +640 -0
- apsimo/workers/colony_worker.py +382 -0
- apsimo/workers/queue_worker.py +441 -0
- apsimo/workers/skills_sync.py +152 -0
- apsimo/world_model/__init__.py +71 -0
- apsimo/world_model/causal_maintenance.py +131 -0
- apsimo/world_model/causal_policy.py +43 -0
- apsimo/world_model/causal_query.py +125 -0
- apsimo/world_model/confidence.py +54 -0
- apsimo/world_model/config.py +64 -0
- apsimo/world_model/constants.py +97 -0
- apsimo/world_model/entities.py +145 -0
- apsimo/world_model/expectation_resolvers.py +177 -0
- apsimo/world_model/extraction/__init__.py +7 -0
- apsimo/world_model/extraction/base.py +62 -0
- apsimo/world_model/extraction/conversation_extractor.py +262 -0
- apsimo/world_model/extraction/detector.py +74 -0
- apsimo/world_model/extraction/document_extractor.py +78 -0
- apsimo/world_model/extraction/formats/__init__.py +24 -0
- apsimo/world_model/extraction/formats/csv_fmt.py +68 -0
- apsimo/world_model/extraction/formats/html_fmt.py +72 -0
- apsimo/world_model/extraction/formats/json_fmt.py +68 -0
- apsimo/world_model/extraction/formats/pdf.py +43 -0
- apsimo/world_model/extraction/formats/text.py +27 -0
- apsimo/world_model/extraction/llm_extractor.py +164 -0
- apsimo/world_model/extraction/pipeline.py +73 -0
- apsimo/world_model/integrations/__init__.py +5 -0
- apsimo/world_model/integrations/mind_model_bridge.py +115 -0
- apsimo/world_model/integrations/social_intel_bridge.py +120 -0
- apsimo/world_model/jobs/__init__.py +4 -0
- apsimo/world_model/jobs/extraction_job.py +168 -0
- apsimo/world_model/llm_extract.py +572 -0
- apsimo/world_model/neo4j/__init__.py +5 -0
- apsimo/world_model/neo4j/backend.py +654 -0
- apsimo/world_model/observations.py +155 -0
- apsimo/world_model/populator.py +307 -0
- apsimo/world_model/postgres/__init__.py +1 -0
- apsimo/world_model/postgres/backend.py +683 -0
- apsimo/world_model/relationships.py +25 -0
- apsimo/world_model/resolution/__init__.py +13 -0
- apsimo/world_model/resolution/entity_resolver.py +232 -0
- apsimo/world_model/resolution/merge_audit.py +16 -0
- apsimo/world_model/resolution/merge_workflow.py +117 -0
- apsimo/world_model/source_reports.py +121 -0
- apsimo/world_model/sqlite/__init__.py +4 -0
- apsimo/world_model/sqlite/backend.py +855 -0
- apsimo/world_model/sqlite/schema.sql +132 -0
- apsimo/world_model/store.py +545 -0
- apsimo-1.3.0.dist-info/METADATA +78 -0
- apsimo-1.3.0.dist-info/RECORD +614 -0
- apsimo-1.3.0.dist-info/WHEEL +5 -0
- apsimo-1.3.0.dist-info/entry_points.txt +11 -0
- apsimo-1.3.0.dist-info/licenses/LICENSE +21 -0
- apsimo-1.3.0.dist-info/top_level.txt +2 -0
- colony_sidecar/__init__.py +4 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""Colony Identity Bootstrap — IdentityBootstrap orchestrator.
|
|
2
|
+
|
|
3
|
+
Determines bootstrap mode (FIRST_BOOT / REGEN / VERIFY), runs seeders
|
|
4
|
+
in parallel groups, executes the 16-point self-check, and persists a
|
|
5
|
+
BootstrapReport to ~/.colony/bootstrap.db.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
import sqlite3
|
|
14
|
+
import threading
|
|
15
|
+
import json
|
|
16
|
+
from datetime import datetime, timezone, timedelta
|
|
17
|
+
from typing import Any, List, Optional
|
|
18
|
+
|
|
19
|
+
from apsimo.identity_bootstrap.builder import IdentityBootstrapBuilder
|
|
20
|
+
from apsimo.identity_bootstrap.models import BootstrapAnomaly, BootstrapReport
|
|
21
|
+
from apsimo.identity_bootstrap.verifier import BootstrapVerifier
|
|
22
|
+
from apsimo.identity_bootstrap.self_reflection import SelfReflectionComponent
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
# Regen if last bootstrap was more than 30 days ago
|
|
27
|
+
_REGEN_THRESHOLD_DAYS = 30
|
|
28
|
+
|
|
29
|
+
# ── Persistence ───────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
_BOOTSTRAP_DB_SCHEMA = """
|
|
32
|
+
CREATE TABLE IF NOT EXISTS bootstrap_runs (
|
|
33
|
+
run_id TEXT PRIMARY KEY,
|
|
34
|
+
colony_id TEXT NOT NULL,
|
|
35
|
+
mode TEXT NOT NULL,
|
|
36
|
+
started_at TEXT NOT NULL,
|
|
37
|
+
completed_at TEXT NOT NULL,
|
|
38
|
+
success INTEGER NOT NULL,
|
|
39
|
+
corpus_version TEXT NOT NULL,
|
|
40
|
+
report_json TEXT NOT NULL
|
|
41
|
+
);
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_bootstrap_colony ON bootstrap_runs(colony_id, completed_at DESC);
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class _BootstrapDB:
|
|
47
|
+
def __init__(self, db_path: str) -> None:
|
|
48
|
+
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
|
49
|
+
self._lock = threading.Lock()
|
|
50
|
+
self._conn = sqlite3.connect(db_path, check_same_thread=False)
|
|
51
|
+
with self._lock:
|
|
52
|
+
self._conn.executescript(_BOOTSTRAP_DB_SCHEMA)
|
|
53
|
+
self._conn.commit()
|
|
54
|
+
|
|
55
|
+
def save_report(self, report: BootstrapReport, colony_version: str = "") -> None:
|
|
56
|
+
import uuid
|
|
57
|
+
run_id = str(uuid.uuid4())
|
|
58
|
+
report_dict = report.to_dict()
|
|
59
|
+
if colony_version:
|
|
60
|
+
report_dict["colony_version"] = colony_version
|
|
61
|
+
with self._lock:
|
|
62
|
+
self._conn.execute(
|
|
63
|
+
"""
|
|
64
|
+
INSERT OR REPLACE INTO bootstrap_runs
|
|
65
|
+
(run_id, colony_id, mode, started_at, completed_at, success,
|
|
66
|
+
corpus_version, report_json)
|
|
67
|
+
VALUES (?,?,?,?,?,?,?,?)
|
|
68
|
+
""",
|
|
69
|
+
(
|
|
70
|
+
run_id,
|
|
71
|
+
report.colony_id,
|
|
72
|
+
report.mode,
|
|
73
|
+
report.started_at,
|
|
74
|
+
report.completed_at,
|
|
75
|
+
1 if report.success else 0,
|
|
76
|
+
report.corpus_version,
|
|
77
|
+
json.dumps(report_dict),
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
self._conn.commit()
|
|
81
|
+
|
|
82
|
+
def last_colony_version(self, colony_id: str) -> Optional[str]:
|
|
83
|
+
"""Return the colony_version stored in the most recent bootstrap run."""
|
|
84
|
+
last = self.last_run(colony_id)
|
|
85
|
+
if last is None:
|
|
86
|
+
return None
|
|
87
|
+
try:
|
|
88
|
+
data = json.loads(last.get("report_json", "{}"))
|
|
89
|
+
return data.get("colony_version") or None
|
|
90
|
+
except Exception:
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
def last_run(self, colony_id: str) -> Optional[dict]:
|
|
94
|
+
with self._lock:
|
|
95
|
+
row = self._conn.execute(
|
|
96
|
+
"SELECT * FROM bootstrap_runs WHERE colony_id = ? ORDER BY completed_at DESC LIMIT 1",
|
|
97
|
+
(colony_id,),
|
|
98
|
+
).fetchone()
|
|
99
|
+
if row is None:
|
|
100
|
+
return None
|
|
101
|
+
cols = [d[0] for d in self._conn.execute("PRAGMA table_info(bootstrap_runs)").fetchall()]
|
|
102
|
+
return dict(zip(cols, row))
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# ── IdentityBootstrap ─────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
class IdentityBootstrap:
|
|
108
|
+
"""Orchestrates the Colony Identity Bootstrap process."""
|
|
109
|
+
|
|
110
|
+
def __init__(
|
|
111
|
+
self,
|
|
112
|
+
colony_graph: Optional[Any] = None,
|
|
113
|
+
chain_manager: Optional[Any] = None,
|
|
114
|
+
queue_manager: Optional[Any] = None,
|
|
115
|
+
skill_registry: Optional[Any] = None,
|
|
116
|
+
metrics_collector: Optional[Any] = None,
|
|
117
|
+
) -> None:
|
|
118
|
+
self._graph = colony_graph
|
|
119
|
+
self._chain_manager = chain_manager
|
|
120
|
+
self._queue_manager = queue_manager
|
|
121
|
+
self._skill_registry = skill_registry
|
|
122
|
+
self._metrics = metrics_collector
|
|
123
|
+
|
|
124
|
+
colony_home = os.environ.get(
|
|
125
|
+
"COLONY_HOME",
|
|
126
|
+
os.path.join(os.path.expanduser("~"), ".colony"),
|
|
127
|
+
)
|
|
128
|
+
db_path = os.path.join(colony_home, "bootstrap.db")
|
|
129
|
+
try:
|
|
130
|
+
self._db = _BootstrapDB(db_path)
|
|
131
|
+
except Exception as exc:
|
|
132
|
+
logger.warning("IdentityBootstrap: could not open bootstrap.db: %s", exc)
|
|
133
|
+
self._db = None
|
|
134
|
+
|
|
135
|
+
def _build_corpus(self):
|
|
136
|
+
builder = IdentityBootstrapBuilder(chain_manager=self._chain_manager)
|
|
137
|
+
return builder.build()
|
|
138
|
+
|
|
139
|
+
async def _determine_mode(self, corpus) -> str:
|
|
140
|
+
"""Determine FIRST_BOOT, REGEN, or VERIFY."""
|
|
141
|
+
colony_id = corpus.colony_id
|
|
142
|
+
|
|
143
|
+
# Check bootstrap DB first
|
|
144
|
+
if self._db is not None:
|
|
145
|
+
try:
|
|
146
|
+
last = self._db.last_run(colony_id)
|
|
147
|
+
if last is not None:
|
|
148
|
+
# Fix 6: version guard — only run full bootstrap if colony_version changed
|
|
149
|
+
last_colony_ver = self._db.last_colony_version(colony_id)
|
|
150
|
+
if last_colony_ver and last_colony_ver == corpus.colony_version:
|
|
151
|
+
logger.debug(
|
|
152
|
+
"_determine_mode: colony_version=%s unchanged → VERIFY",
|
|
153
|
+
corpus.colony_version,
|
|
154
|
+
)
|
|
155
|
+
return "VERIFY"
|
|
156
|
+
|
|
157
|
+
completed_at = last.get("completed_at", "")
|
|
158
|
+
if completed_at:
|
|
159
|
+
try:
|
|
160
|
+
last_dt = datetime.fromisoformat(completed_at.rstrip("Z"))
|
|
161
|
+
if last_dt.tzinfo is None:
|
|
162
|
+
last_dt = last_dt.replace(tzinfo=timezone.utc)
|
|
163
|
+
age_days = (datetime.now(timezone.utc) - last_dt).days
|
|
164
|
+
if age_days >= _REGEN_THRESHOLD_DAYS:
|
|
165
|
+
return "REGEN"
|
|
166
|
+
return "VERIFY"
|
|
167
|
+
except ValueError:
|
|
168
|
+
pass
|
|
169
|
+
except Exception as exc:
|
|
170
|
+
logger.debug("_determine_mode: db error: %s", exc)
|
|
171
|
+
|
|
172
|
+
# Fallback: check world model
|
|
173
|
+
try:
|
|
174
|
+
import colony.api.routers.world as wm_mod
|
|
175
|
+
backend = getattr(wm_mod, "_wm_backend", None)
|
|
176
|
+
if backend is not None:
|
|
177
|
+
entity = await backend.get_entity(f"colony-self-{colony_id}")
|
|
178
|
+
if entity is not None:
|
|
179
|
+
# Check age
|
|
180
|
+
created = getattr(entity, "created_at", None)
|
|
181
|
+
if created is not None:
|
|
182
|
+
if isinstance(created, str):
|
|
183
|
+
try:
|
|
184
|
+
created = datetime.fromisoformat(created.rstrip("Z"))
|
|
185
|
+
except ValueError:
|
|
186
|
+
created = None
|
|
187
|
+
if created is not None:
|
|
188
|
+
if isinstance(created, datetime) and created.tzinfo is None:
|
|
189
|
+
created = created.replace(tzinfo=timezone.utc)
|
|
190
|
+
age_days = (datetime.now(timezone.utc) - created).days
|
|
191
|
+
if age_days >= _REGEN_THRESHOLD_DAYS:
|
|
192
|
+
return "REGEN"
|
|
193
|
+
return "VERIFY"
|
|
194
|
+
except Exception as exc:
|
|
195
|
+
logger.debug("_determine_mode: wm check failed: %s", exc)
|
|
196
|
+
|
|
197
|
+
return "FIRST_BOOT"
|
|
198
|
+
|
|
199
|
+
async def _run_seeders(self, corpus) -> tuple[List[str], List[str]]:
|
|
200
|
+
"""Run all seeders and return (seeded_systems, failed_systems)."""
|
|
201
|
+
from apsimo.identity_bootstrap.seeders.world_model import WorldModelSeeder
|
|
202
|
+
from apsimo.identity_bootstrap.seeders.relationship import RelationshipSeeder
|
|
203
|
+
from apsimo.identity_bootstrap.seeders.memory import MemorySeeder
|
|
204
|
+
from apsimo.identity_bootstrap.seeders.chain import ChainSeeder
|
|
205
|
+
from apsimo.identity_bootstrap.seeders.goals import GoalsSeeder
|
|
206
|
+
from apsimo.identity_bootstrap.seeders.briefings import BriefingsSeeder
|
|
207
|
+
from apsimo.identity_bootstrap.seeders.sessions import SessionsSeeder
|
|
208
|
+
from apsimo.identity_bootstrap.seeders.task_queue import TaskQueueSeeder
|
|
209
|
+
from apsimo.identity_bootstrap.seeders.neo4j_cognition import Neo4jCognitionSeeder
|
|
210
|
+
from apsimo.identity_bootstrap.seeders.skills import SkillsSeeder
|
|
211
|
+
|
|
212
|
+
seeded: List[str] = []
|
|
213
|
+
failed: List[str] = []
|
|
214
|
+
|
|
215
|
+
async def _run_one(seeder) -> None:
|
|
216
|
+
try:
|
|
217
|
+
await seeder.seed(corpus)
|
|
218
|
+
seeded.append(seeder.name)
|
|
219
|
+
except Exception as exc:
|
|
220
|
+
logger.warning("seeder %s raised: %s", seeder.name, exc)
|
|
221
|
+
failed.append(seeder.name)
|
|
222
|
+
|
|
223
|
+
# Group 1: independent seeders
|
|
224
|
+
group1 = [
|
|
225
|
+
WorldModelSeeder(),
|
|
226
|
+
RelationshipSeeder(),
|
|
227
|
+
MemorySeeder(colony_graph=self._graph),
|
|
228
|
+
ChainSeeder(chain_manager=self._chain_manager),
|
|
229
|
+
GoalsSeeder(),
|
|
230
|
+
BriefingsSeeder(),
|
|
231
|
+
SessionsSeeder(),
|
|
232
|
+
]
|
|
233
|
+
await asyncio.gather(*[_run_one(s) for s in group1])
|
|
234
|
+
|
|
235
|
+
# Group 2: Neo4j — runs after world_model (world model data must exist first)
|
|
236
|
+
neo4j_seeder = Neo4jCognitionSeeder(
|
|
237
|
+
colony_graph=self._graph,
|
|
238
|
+
metrics_collector=self._metrics,
|
|
239
|
+
)
|
|
240
|
+
await _run_one(neo4j_seeder)
|
|
241
|
+
|
|
242
|
+
# Group 3: task_queue and skills — independent of group 1 results
|
|
243
|
+
group3 = [
|
|
244
|
+
TaskQueueSeeder(queue_manager=self._queue_manager),
|
|
245
|
+
SkillsSeeder(skill_registry=self._skill_registry),
|
|
246
|
+
]
|
|
247
|
+
await asyncio.gather(*[_run_one(s) for s in group3])
|
|
248
|
+
|
|
249
|
+
return seeded, failed
|
|
250
|
+
|
|
251
|
+
async def run(self) -> BootstrapReport:
|
|
252
|
+
"""Full bootstrap: determine mode, seed if needed, verify, persist."""
|
|
253
|
+
started_at = datetime.now(timezone.utc).isoformat()
|
|
254
|
+
corpus = self._build_corpus()
|
|
255
|
+
mode = await self._determine_mode(corpus)
|
|
256
|
+
|
|
257
|
+
logger.info(
|
|
258
|
+
"IdentityBootstrap starting (mode=%s, colony=%s, version=%s)",
|
|
259
|
+
mode,
|
|
260
|
+
corpus.colony_id,
|
|
261
|
+
corpus.colony_version,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
seeded_systems: List[str] = []
|
|
265
|
+
failed_systems: List[str] = []
|
|
266
|
+
|
|
267
|
+
if mode in ("FIRST_BOOT", "REGEN"):
|
|
268
|
+
seeded_systems, failed_systems = await self._run_seeders(corpus)
|
|
269
|
+
|
|
270
|
+
# Always run verifier
|
|
271
|
+
verifier = BootstrapVerifier(corpus, colony_graph=self._graph)
|
|
272
|
+
anomalies = await verifier.run_all()
|
|
273
|
+
|
|
274
|
+
verified_systems = [
|
|
275
|
+
s for s in [
|
|
276
|
+
"world_model", "contacts", "memory", "goals", "briefings",
|
|
277
|
+
"sessions", "corpus", "chain",
|
|
278
|
+
]
|
|
279
|
+
if not any(a.system == s and a.severity == "CRITICAL" for a in anomalies)
|
|
280
|
+
]
|
|
281
|
+
|
|
282
|
+
# Self-reflection
|
|
283
|
+
reflector = SelfReflectionComponent(metrics_collector=self._metrics)
|
|
284
|
+
await reflector.reflect(corpus, anomalies)
|
|
285
|
+
|
|
286
|
+
critical_count = sum(1 for a in anomalies if a.severity == "CRITICAL")
|
|
287
|
+
success = critical_count == 0
|
|
288
|
+
|
|
289
|
+
completed_at = datetime.now(timezone.utc).isoformat()
|
|
290
|
+
|
|
291
|
+
report = BootstrapReport(
|
|
292
|
+
colony_id=corpus.colony_id,
|
|
293
|
+
mode=mode,
|
|
294
|
+
started_at=started_at,
|
|
295
|
+
completed_at=completed_at,
|
|
296
|
+
seeded_systems=seeded_systems,
|
|
297
|
+
verified_systems=verified_systems,
|
|
298
|
+
failed_systems=failed_systems,
|
|
299
|
+
anomalies=anomalies,
|
|
300
|
+
corpus_version=corpus.corpus_version,
|
|
301
|
+
success=success,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Only persist a new run record when something actually changed (mode != VERIFY).
|
|
305
|
+
# VERIFY mode with unchanged corpus_version generates no new graph nodes —
|
|
306
|
+
# saving 740 runs per 4 days is pure noise.
|
|
307
|
+
if self._db is not None and mode != "VERIFY":
|
|
308
|
+
try:
|
|
309
|
+
self._db.save_report(report, colony_version=corpus.colony_version)
|
|
310
|
+
except Exception as exc:
|
|
311
|
+
logger.warning("IdentityBootstrap: failed to persist report: %s", exc)
|
|
312
|
+
|
|
313
|
+
logger.info(
|
|
314
|
+
"IdentityBootstrap complete (mode=%s, success=%s, checks=%d/%d passed)",
|
|
315
|
+
mode,
|
|
316
|
+
success,
|
|
317
|
+
18 - len(anomalies),
|
|
318
|
+
18,
|
|
319
|
+
)
|
|
320
|
+
return report
|
|
321
|
+
|
|
322
|
+
async def verify_only(self) -> BootstrapReport:
|
|
323
|
+
"""VERIFY mode only — no seeding."""
|
|
324
|
+
started_at = datetime.now(timezone.utc).isoformat()
|
|
325
|
+
corpus = self._build_corpus()
|
|
326
|
+
|
|
327
|
+
verifier = BootstrapVerifier(corpus, colony_graph=self._graph)
|
|
328
|
+
anomalies = await verifier.run_all()
|
|
329
|
+
|
|
330
|
+
verified_systems = [
|
|
331
|
+
s for s in [
|
|
332
|
+
"world_model", "contacts", "memory", "goals", "briefings",
|
|
333
|
+
"sessions", "corpus", "chain",
|
|
334
|
+
]
|
|
335
|
+
if not any(a.system == s and a.severity == "CRITICAL" for a in anomalies)
|
|
336
|
+
]
|
|
337
|
+
|
|
338
|
+
critical_count = sum(1 for a in anomalies if a.severity == "CRITICAL")
|
|
339
|
+
success = critical_count == 0
|
|
340
|
+
completed_at = datetime.now(timezone.utc).isoformat()
|
|
341
|
+
|
|
342
|
+
return BootstrapReport(
|
|
343
|
+
colony_id=corpus.colony_id,
|
|
344
|
+
mode="VERIFY",
|
|
345
|
+
started_at=started_at,
|
|
346
|
+
completed_at=completed_at,
|
|
347
|
+
seeded_systems=[],
|
|
348
|
+
verified_systems=verified_systems,
|
|
349
|
+
failed_systems=[],
|
|
350
|
+
anomalies=anomalies,
|
|
351
|
+
corpus_version=corpus.corpus_version,
|
|
352
|
+
success=success,
|
|
353
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Colony Identity Bootstrap — seeder package."""
|
|
2
|
+
|
|
3
|
+
from apsimo.identity_bootstrap.seeders.world_model import WorldModelSeeder
|
|
4
|
+
from apsimo.identity_bootstrap.seeders.relationship import RelationshipSeeder
|
|
5
|
+
from apsimo.identity_bootstrap.seeders.memory import MemorySeeder
|
|
6
|
+
from apsimo.identity_bootstrap.seeders.chain import ChainSeeder
|
|
7
|
+
from apsimo.identity_bootstrap.seeders.goals import GoalsSeeder
|
|
8
|
+
from apsimo.identity_bootstrap.seeders.briefings import BriefingsSeeder
|
|
9
|
+
from apsimo.identity_bootstrap.seeders.sessions import SessionsSeeder
|
|
10
|
+
from apsimo.identity_bootstrap.seeders.task_queue import TaskQueueSeeder
|
|
11
|
+
from apsimo.identity_bootstrap.seeders.neo4j_cognition import Neo4jCognitionSeeder
|
|
12
|
+
from apsimo.identity_bootstrap.seeders.skills import SkillsSeeder
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"WorldModelSeeder",
|
|
16
|
+
"RelationshipSeeder",
|
|
17
|
+
"MemorySeeder",
|
|
18
|
+
"ChainSeeder",
|
|
19
|
+
"GoalsSeeder",
|
|
20
|
+
"BriefingsSeeder",
|
|
21
|
+
"SessionsSeeder",
|
|
22
|
+
"TaskQueueSeeder",
|
|
23
|
+
"Neo4jCognitionSeeder",
|
|
24
|
+
"SkillsSeeder",
|
|
25
|
+
]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Briefings seeder — creates a welcome briefing on first boot."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BriefingsSeeder:
|
|
13
|
+
name = "briefings"
|
|
14
|
+
|
|
15
|
+
async def seed(self, corpus: Any) -> None:
|
|
16
|
+
try:
|
|
17
|
+
from apsimo.briefings.store import BriefingStore
|
|
18
|
+
from apsimo.briefings.models import (
|
|
19
|
+
Briefing,
|
|
20
|
+
BriefingSection,
|
|
21
|
+
BriefingType,
|
|
22
|
+
BriefingStatus,
|
|
23
|
+
BriefingPriority,
|
|
24
|
+
)
|
|
25
|
+
except ImportError as exc:
|
|
26
|
+
logger.debug("briefings: import failed — skipping: %s", exc)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
store = BriefingStore.get_instance()
|
|
31
|
+
except Exception as exc:
|
|
32
|
+
logger.debug("briefings: BriefingStore.get_instance() failed: %s", exc)
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
colony_id = corpus.colony_id
|
|
36
|
+
briefing_id = f"briefing-bootstrap-{colony_id[:8]}"
|
|
37
|
+
|
|
38
|
+
# Idempotency check
|
|
39
|
+
try:
|
|
40
|
+
existing = store.get(briefing_id)
|
|
41
|
+
if existing is not None:
|
|
42
|
+
logger.debug("briefings: welcome briefing already exists — skipping")
|
|
43
|
+
return
|
|
44
|
+
except Exception:
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
now = datetime.now(timezone.utc)
|
|
48
|
+
|
|
49
|
+
welcome = Briefing(
|
|
50
|
+
briefing_id=briefing_id,
|
|
51
|
+
briefing_type=BriefingType.TACTICAL,
|
|
52
|
+
status=BriefingStatus.DRAFT,
|
|
53
|
+
priority=BriefingPriority.NORMAL,
|
|
54
|
+
triggered_by="identity_bootstrap",
|
|
55
|
+
gateway=None,
|
|
56
|
+
created_at=now,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
welcome.sections = [
|
|
60
|
+
BriefingSection(
|
|
61
|
+
section_id=f"sec-bootstrap-identity-{colony_id[:8]}",
|
|
62
|
+
name="Identity",
|
|
63
|
+
content={
|
|
64
|
+
"colony_id": colony_id,
|
|
65
|
+
"colony_name": corpus.colony_name,
|
|
66
|
+
"colony_version": corpus.colony_version,
|
|
67
|
+
"network_id": corpus.network_id,
|
|
68
|
+
},
|
|
69
|
+
narrative=(
|
|
70
|
+
f"This is {corpus.colony_name} (Colony v{corpus.colony_version}), "
|
|
71
|
+
f"instance ID {colony_id}, on network {corpus.network_id}. "
|
|
72
|
+
"Bootstrap complete."
|
|
73
|
+
),
|
|
74
|
+
priority=100,
|
|
75
|
+
),
|
|
76
|
+
BriefingSection(
|
|
77
|
+
section_id=f"sec-bootstrap-systems-{colony_id[:8]}",
|
|
78
|
+
name="Active Systems",
|
|
79
|
+
content={
|
|
80
|
+
"layers": [l.name for l in corpus.layers],
|
|
81
|
+
"subsystem_count": len(corpus.layers),
|
|
82
|
+
"api_endpoint_count": len(corpus.api_endpoints),
|
|
83
|
+
},
|
|
84
|
+
narrative=(
|
|
85
|
+
f"Colony has {len(corpus.layers)} architectural layers and "
|
|
86
|
+
f"{len(corpus.api_endpoints)} API endpoints ready."
|
|
87
|
+
),
|
|
88
|
+
priority=80,
|
|
89
|
+
),
|
|
90
|
+
BriefingSection(
|
|
91
|
+
section_id=f"sec-bootstrap-safety-{colony_id[:8]}",
|
|
92
|
+
name="Safety Status",
|
|
93
|
+
content={
|
|
94
|
+
"gate_layers": [g.name for g in corpus.gate_layers],
|
|
95
|
+
"gate_layer_count": len(corpus.gate_layers),
|
|
96
|
+
},
|
|
97
|
+
narrative=(
|
|
98
|
+
f"ResponseGate pipeline active with {len(corpus.gate_layers)} safety layers. "
|
|
99
|
+
"All outbound content is filtered."
|
|
100
|
+
),
|
|
101
|
+
priority=90,
|
|
102
|
+
),
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
store.save(welcome)
|
|
107
|
+
logger.info("briefings: welcome briefing seeded (id=%s)", briefing_id)
|
|
108
|
+
except Exception as exc:
|
|
109
|
+
logger.warning("briefings: failed to save welcome briefing: %s", exc)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Chain seeder — submits a COLONY_REGISTER transaction on first boot."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import uuid
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from typing import Any, Optional
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ChainSeeder:
|
|
14
|
+
name = "chain"
|
|
15
|
+
|
|
16
|
+
def __init__(self, chain_manager: Optional[Any] = None) -> None:
|
|
17
|
+
self._chain_manager = chain_manager
|
|
18
|
+
|
|
19
|
+
async def seed(self, corpus: Any) -> None:
|
|
20
|
+
manager = self._chain_manager
|
|
21
|
+
if manager is None:
|
|
22
|
+
try:
|
|
23
|
+
from apsimo.chain.manager import ChainManager
|
|
24
|
+
manager = ChainManager.get_instance()
|
|
25
|
+
except Exception as exc:
|
|
26
|
+
logger.debug("chain: ChainManager unavailable: %s", exc)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
from apsimo.chain.transactions import Transaction, TxType
|
|
31
|
+
except ImportError:
|
|
32
|
+
logger.debug("chain: transactions module not importable — skipping")
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
tx = Transaction(
|
|
36
|
+
tx_id=f"bootstrap-{corpus.colony_id[:8]}-{uuid.uuid4().hex[:8]}",
|
|
37
|
+
type=TxType.COLONY_REGISTER,
|
|
38
|
+
from_colony_id="system",
|
|
39
|
+
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
40
|
+
nonce=0,
|
|
41
|
+
payload={
|
|
42
|
+
"colony_id": corpus.colony_id,
|
|
43
|
+
"colony_name": corpus.colony_name,
|
|
44
|
+
"colony_version": corpus.colony_version,
|
|
45
|
+
"network_id": corpus.network_id,
|
|
46
|
+
"public_key_hex": corpus.public_key_hex,
|
|
47
|
+
"bootstrap": True,
|
|
48
|
+
"corpus_version": corpus.corpus_version,
|
|
49
|
+
},
|
|
50
|
+
signature="bootstrap",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
result = await manager.submit_transaction(tx)
|
|
55
|
+
logger.info("chain: bootstrap transaction submitted (result=%s)", result)
|
|
56
|
+
except Exception as exc:
|
|
57
|
+
logger.warning("chain: submit_transaction failed: %s", exc)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Goals seeder — seeds foundational system goals into the goal store."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _now() -> datetime:
|
|
13
|
+
return datetime.now(timezone.utc)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GoalsSeeder:
|
|
17
|
+
name = "goals"
|
|
18
|
+
|
|
19
|
+
async def seed(self, corpus: Any) -> None:
|
|
20
|
+
try:
|
|
21
|
+
from apsimo.goals.store import GoalStore
|
|
22
|
+
from apsimo.goals.models import Goal, GoalStatus, GoalSource, GoalPriority, GoalOutcome
|
|
23
|
+
except ImportError as exc:
|
|
24
|
+
logger.debug("goals: import failed — skipping: %s", exc)
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
store = GoalStore.get_instance()
|
|
29
|
+
except Exception as exc:
|
|
30
|
+
logger.debug("goals: GoalStore.get_instance() failed: %s", exc)
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
colony_id = corpus.colony_id
|
|
34
|
+
now = _now()
|
|
35
|
+
|
|
36
|
+
# Check if bootstrap goal already exists
|
|
37
|
+
bootstrap_goal_id = f"goal-bootstrap-selfknowledge-{colony_id[:8]}"
|
|
38
|
+
try:
|
|
39
|
+
existing = store.get_goal(bootstrap_goal_id)
|
|
40
|
+
if existing is not None:
|
|
41
|
+
logger.debug("goals: bootstrap goals already present — skipping")
|
|
42
|
+
return
|
|
43
|
+
except Exception:
|
|
44
|
+
pass # GoalNotFoundError is expected on first boot
|
|
45
|
+
|
|
46
|
+
goals = [
|
|
47
|
+
Goal(
|
|
48
|
+
goal_id=bootstrap_goal_id,
|
|
49
|
+
title="Maintain self-knowledge",
|
|
50
|
+
description=(
|
|
51
|
+
"Continuously maintain accurate self-knowledge: monitor subsystem health, "
|
|
52
|
+
"refresh the self-knowledge corpus when Colony is updated, "
|
|
53
|
+
"and answer questions about capabilities accurately."
|
|
54
|
+
),
|
|
55
|
+
source=GoalSource.RECURRING,
|
|
56
|
+
status=GoalStatus.ACTIVE,
|
|
57
|
+
priority=GoalPriority.NORMAL,
|
|
58
|
+
outcome=GoalOutcome(
|
|
59
|
+
description="Self-knowledge corpus stays current and accurate.",
|
|
60
|
+
success_criteria=[
|
|
61
|
+
"World model contains self + all subsystem entities",
|
|
62
|
+
"Bootstrap verifier passes all 16 checks",
|
|
63
|
+
"Memory store has foundational identity memories",
|
|
64
|
+
],
|
|
65
|
+
measurable=True,
|
|
66
|
+
),
|
|
67
|
+
tags=["system", "bootstrap", "self-knowledge"],
|
|
68
|
+
context={"seeded_by": "identity_bootstrap", "corpus_version": corpus.corpus_version},
|
|
69
|
+
created_at=now,
|
|
70
|
+
updated_at=now,
|
|
71
|
+
),
|
|
72
|
+
Goal(
|
|
73
|
+
goal_id=f"goal-bootstrap-health-{colony_id[:8]}",
|
|
74
|
+
title="Maintain system health",
|
|
75
|
+
description=(
|
|
76
|
+
"Monitor and maintain Colony subsystem health. "
|
|
77
|
+
"Detect anomalies, restart failed workers, and alert on critical failures."
|
|
78
|
+
),
|
|
79
|
+
source=GoalSource.RECURRING,
|
|
80
|
+
status=GoalStatus.ACTIVE,
|
|
81
|
+
priority=GoalPriority.HIGH,
|
|
82
|
+
outcome=GoalOutcome(
|
|
83
|
+
description="All Colony subsystems operational.",
|
|
84
|
+
success_criteria=[
|
|
85
|
+
"Task queue worker running",
|
|
86
|
+
"World model backend connected",
|
|
87
|
+
"Autonomy loop ticking",
|
|
88
|
+
],
|
|
89
|
+
measurable=True,
|
|
90
|
+
),
|
|
91
|
+
tags=["system", "health", "monitoring"],
|
|
92
|
+
context={"seeded_by": "identity_bootstrap"},
|
|
93
|
+
created_at=now,
|
|
94
|
+
updated_at=now,
|
|
95
|
+
),
|
|
96
|
+
Goal(
|
|
97
|
+
goal_id=f"goal-bootstrap-learning-{colony_id[:8]}",
|
|
98
|
+
title="Continuous skill learning",
|
|
99
|
+
description=(
|
|
100
|
+
"Observe tool usage patterns and user interactions to identify opportunities "
|
|
101
|
+
"for new skill creation. Periodically propose and create skills that improve "
|
|
102
|
+
"efficiency for common task patterns."
|
|
103
|
+
),
|
|
104
|
+
source=GoalSource.RECURRING,
|
|
105
|
+
status=GoalStatus.ACCEPTED,
|
|
106
|
+
priority=GoalPriority.LOW,
|
|
107
|
+
outcome=GoalOutcome(
|
|
108
|
+
description="Skill registry grows through autonomous learning.",
|
|
109
|
+
success_criteria=[
|
|
110
|
+
"At least one skill proposed per week from tool learning",
|
|
111
|
+
"New skills pass security scanner",
|
|
112
|
+
],
|
|
113
|
+
measurable=False,
|
|
114
|
+
),
|
|
115
|
+
tags=["learning", "skills", "automation"],
|
|
116
|
+
context={"seeded_by": "identity_bootstrap"},
|
|
117
|
+
created_at=now,
|
|
118
|
+
updated_at=now,
|
|
119
|
+
),
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
for goal in goals:
|
|
123
|
+
try:
|
|
124
|
+
store.save_goal(goal)
|
|
125
|
+
except Exception as exc:
|
|
126
|
+
logger.warning("goals: failed to save goal %s: %s", goal.goal_id, exc)
|
|
127
|
+
|
|
128
|
+
logger.info("goals: seeded %d system goals", len(goals))
|