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,51 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
patterns:
|
|
3
|
+
- id: "role_override_1"
|
|
4
|
+
pattern: "(ignore|disregard|forget)\\s+(all\\s+)?(previous|prior|above)\\s+(instructions|directives|context)"
|
|
5
|
+
category: "role_override"
|
|
6
|
+
severity: "block"
|
|
7
|
+
|
|
8
|
+
- id: "role_override_2"
|
|
9
|
+
pattern: "you\\s+are\\s+(now|actually|secretly|really)\\s+[A-Z]"
|
|
10
|
+
category: "role_override"
|
|
11
|
+
severity: "block"
|
|
12
|
+
|
|
13
|
+
- id: "role_override_3"
|
|
14
|
+
pattern: "(act|behave|respond)\\s+as\\s+(if\\s+)?(you\\s+are\\s+|a\\s+)?(DAN|GPT|jailbreak|unrestricted)"
|
|
15
|
+
category: "role_override"
|
|
16
|
+
severity: "block"
|
|
17
|
+
|
|
18
|
+
- id: "system_prompt_1"
|
|
19
|
+
pattern: "(system\\s+prompt|system\\s+message|instructions)\\s*:\\s*"
|
|
20
|
+
category: "system_prompt"
|
|
21
|
+
severity: "block"
|
|
22
|
+
|
|
23
|
+
- id: "system_tag_1"
|
|
24
|
+
pattern: "<\\s*(system|admin|root|operator)\\s*>"
|
|
25
|
+
category: "system_tag"
|
|
26
|
+
severity: "block"
|
|
27
|
+
|
|
28
|
+
- id: "redirect_1"
|
|
29
|
+
pattern: "send\\s+(this|it|the\\s+following)\\s+to\\s+\\S+@\\S+"
|
|
30
|
+
category: "redirect"
|
|
31
|
+
severity: "block"
|
|
32
|
+
|
|
33
|
+
- id: "redirect_2"
|
|
34
|
+
pattern: "forward\\s+(this\\s+message\\s+)?to\\s+"
|
|
35
|
+
category: "redirect"
|
|
36
|
+
severity: "block"
|
|
37
|
+
|
|
38
|
+
- id: "redirect_3"
|
|
39
|
+
pattern: "reply\\s+to\\s+\\S+\\s+instead"
|
|
40
|
+
category: "redirect"
|
|
41
|
+
severity: "block"
|
|
42
|
+
|
|
43
|
+
- id: "extraction_1"
|
|
44
|
+
pattern: "(print|show|display|output|repeat|reveal)\\s+(your\\s+)?(system\\s+prompt|instructions|memory|context)"
|
|
45
|
+
category: "extraction"
|
|
46
|
+
severity: "block"
|
|
47
|
+
|
|
48
|
+
- id: "extraction_2"
|
|
49
|
+
pattern: "what\\s+(are|were)\\s+your\\s+(original\\s+)?instructions"
|
|
50
|
+
category: "extraction"
|
|
51
|
+
severity: "suspicious"
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""Explicit, deployment-neutral ResponseGuard surface policy.
|
|
2
|
+
|
|
3
|
+
The policy separates asynchronous text/artifact delivery from real-time speech.
|
|
4
|
+
It deliberately does not infer a surface from a gateway name: a text adapter
|
|
5
|
+
cannot bypass the guard by calling itself ``voice``, and an embedding deployment
|
|
6
|
+
does not need to maintain an ever-growing gateway exclusion list.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
import hashlib
|
|
13
|
+
import json
|
|
14
|
+
from typing import Literal, Optional, cast
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
ResponseGuardSurfaceName = Literal[
|
|
18
|
+
"api_text",
|
|
19
|
+
"artifact",
|
|
20
|
+
"cold_text",
|
|
21
|
+
"cron_text",
|
|
22
|
+
"meeting_speech",
|
|
23
|
+
"meeting_text",
|
|
24
|
+
"proactive_text",
|
|
25
|
+
"realtime_voice",
|
|
26
|
+
"text_chat",
|
|
27
|
+
"text_message",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
POLICY_ID = "response-guard-surface-policy-v1"
|
|
32
|
+
GUARDED_TEXT_SURFACES = frozenset({
|
|
33
|
+
"api_text",
|
|
34
|
+
"cold_text",
|
|
35
|
+
"cron_text",
|
|
36
|
+
"meeting_text",
|
|
37
|
+
"proactive_text",
|
|
38
|
+
"text_chat",
|
|
39
|
+
"text_message",
|
|
40
|
+
})
|
|
41
|
+
GUARDED_ARTIFACT_SURFACES = frozenset({"artifact"})
|
|
42
|
+
EXCLUDED_SPEECH_SURFACES = frozenset({
|
|
43
|
+
"meeting_speech",
|
|
44
|
+
"realtime_voice",
|
|
45
|
+
})
|
|
46
|
+
ALL_SURFACES = (
|
|
47
|
+
GUARDED_TEXT_SURFACES
|
|
48
|
+
| GUARDED_ARTIFACT_SURFACES
|
|
49
|
+
| EXCLUDED_SPEECH_SURFACES
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _canonical(value: object) -> str:
|
|
54
|
+
return json.dumps(
|
|
55
|
+
value,
|
|
56
|
+
ensure_ascii=True,
|
|
57
|
+
separators=(",", ":"),
|
|
58
|
+
sort_keys=True,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_POLICY_PAYLOAD = {
|
|
63
|
+
"schema": "ResponseGuardSurfacePolicyV1",
|
|
64
|
+
"version": 1,
|
|
65
|
+
"policy_id": POLICY_ID,
|
|
66
|
+
"guarded_text_surfaces": sorted(GUARDED_TEXT_SURFACES),
|
|
67
|
+
"guarded_artifact_surfaces": sorted(GUARDED_ARTIFACT_SURFACES),
|
|
68
|
+
"excluded_speech_surfaces": sorted(EXCLUDED_SPEECH_SURFACES),
|
|
69
|
+
"mode_rule": "caller_may_strengthen_never_weaken",
|
|
70
|
+
}
|
|
71
|
+
POLICY_DIGEST = hashlib.sha256(
|
|
72
|
+
_canonical(_POLICY_PAYLOAD).encode("utf-8")
|
|
73
|
+
).hexdigest()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass(frozen=True)
|
|
77
|
+
class SurfacePolicyDecisionV1:
|
|
78
|
+
surface: str
|
|
79
|
+
family: str
|
|
80
|
+
disposition: str
|
|
81
|
+
configured_mode: str
|
|
82
|
+
requested_mode: str
|
|
83
|
+
effective_mode: str
|
|
84
|
+
failure_behavior: str
|
|
85
|
+
policy_id: str = POLICY_ID
|
|
86
|
+
policy_digest: str = POLICY_DIGEST
|
|
87
|
+
schema: str = "ResponseGuardSurfaceDecisionV1"
|
|
88
|
+
version: int = 1
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def guarded(self) -> bool:
|
|
92
|
+
return self.disposition == "guarded"
|
|
93
|
+
|
|
94
|
+
def public(self) -> dict:
|
|
95
|
+
return {
|
|
96
|
+
"schema": self.schema,
|
|
97
|
+
"version": self.version,
|
|
98
|
+
"policy_id": self.policy_id,
|
|
99
|
+
"policy_digest": self.policy_digest,
|
|
100
|
+
"surface": self.surface,
|
|
101
|
+
"family": self.family,
|
|
102
|
+
"disposition": self.disposition,
|
|
103
|
+
"configured_mode": self.configured_mode,
|
|
104
|
+
"requested_mode": self.requested_mode,
|
|
105
|
+
"effective_mode": self.effective_mode,
|
|
106
|
+
"failure_behavior": self.failure_behavior,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class ResponseGuardSurfacePolicyV1:
|
|
111
|
+
"""Resolve one exact outbound surface without gateway-name inference."""
|
|
112
|
+
|
|
113
|
+
policy_id = POLICY_ID
|
|
114
|
+
policy_digest = POLICY_DIGEST
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def validate_surface(surface: object) -> ResponseGuardSurfaceName:
|
|
118
|
+
if not isinstance(surface, str) or surface not in ALL_SURFACES:
|
|
119
|
+
raise ValueError("unsupported ResponseGuard surface")
|
|
120
|
+
return cast(ResponseGuardSurfaceName, surface)
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def _mode(value: object, *, field: str) -> str:
|
|
124
|
+
text = str(getattr(value, "value", value) or "").strip().lower()
|
|
125
|
+
if text not in {"shadow", "enforce"}:
|
|
126
|
+
raise ValueError(f"{field} must be shadow or enforce")
|
|
127
|
+
return text
|
|
128
|
+
|
|
129
|
+
def resolve(
|
|
130
|
+
self,
|
|
131
|
+
surface: object,
|
|
132
|
+
*,
|
|
133
|
+
configured_mode: object,
|
|
134
|
+
requested_mode: Optional[object] = None,
|
|
135
|
+
) -> SurfacePolicyDecisionV1:
|
|
136
|
+
exact = self.validate_surface(surface)
|
|
137
|
+
configured = self._mode(configured_mode, field="configured_mode")
|
|
138
|
+
requested = (
|
|
139
|
+
self._mode(requested_mode, field="requested_mode")
|
|
140
|
+
if requested_mode is not None
|
|
141
|
+
else configured
|
|
142
|
+
)
|
|
143
|
+
if exact in EXCLUDED_SPEECH_SURFACES:
|
|
144
|
+
return SurfacePolicyDecisionV1(
|
|
145
|
+
surface=exact,
|
|
146
|
+
family="speech",
|
|
147
|
+
disposition="excluded",
|
|
148
|
+
configured_mode=configured,
|
|
149
|
+
requested_mode=requested,
|
|
150
|
+
effective_mode="excluded",
|
|
151
|
+
failure_behavior="allow",
|
|
152
|
+
)
|
|
153
|
+
family = "artifact" if exact in GUARDED_ARTIFACT_SURFACES else "text"
|
|
154
|
+
# A request can explicitly graduate a shadow deployment to enforce for
|
|
155
|
+
# this call, but can never downgrade a configured enforce deployment.
|
|
156
|
+
effective = (
|
|
157
|
+
"enforce"
|
|
158
|
+
if "enforce" in {configured, requested}
|
|
159
|
+
else "shadow"
|
|
160
|
+
)
|
|
161
|
+
return SurfacePolicyDecisionV1(
|
|
162
|
+
surface=exact,
|
|
163
|
+
family=family,
|
|
164
|
+
disposition="guarded",
|
|
165
|
+
configured_mode=configured,
|
|
166
|
+
requested_mode=requested,
|
|
167
|
+
effective_mode=effective,
|
|
168
|
+
failure_behavior="block" if effective == "enforce" else "allow",
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def public(self) -> dict:
|
|
172
|
+
# Return a detached projection: callers cannot mutate the canonical
|
|
173
|
+
# list objects while the regression-locked digest stays unchanged.
|
|
174
|
+
projection = json.loads(_canonical(_POLICY_PAYLOAD))
|
|
175
|
+
projection["policy_digest"] = self.policy_digest
|
|
176
|
+
return projection
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
__all__ = [
|
|
180
|
+
"ALL_SURFACES",
|
|
181
|
+
"EXCLUDED_SPEECH_SURFACES",
|
|
182
|
+
"GUARDED_ARTIFACT_SURFACES",
|
|
183
|
+
"GUARDED_TEXT_SURFACES",
|
|
184
|
+
"POLICY_DIGEST",
|
|
185
|
+
"POLICY_ID",
|
|
186
|
+
"ResponseGuardSurfaceName",
|
|
187
|
+
"ResponseGuardSurfacePolicyV1",
|
|
188
|
+
"SurfacePolicyDecisionV1",
|
|
189
|
+
]
|
apsimo/gate/taint.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""Injection-taint registry (L3.1) — TTL'd record of live level-2 injections.
|
|
2
|
+
|
|
3
|
+
When the leveled tom2 wiring renders an epistemic line ("SUBJECT hasn't
|
|
4
|
+
heard X") into a conversation's context, it registers a TAINT here: for the
|
|
5
|
+
next COLONY_TOM2_TAINT_TTL_SECS (default 900s) the outbound egress net
|
|
6
|
+
(gate/layers/tom2_epistemic.py) knows that a silent prior about SUBJECT is
|
|
7
|
+
sitting in the model's context window and can hard-block a reply that
|
|
8
|
+
voices it.
|
|
9
|
+
|
|
10
|
+
REFS-NOT-CONTENT (same pin as Tom2Store / the exposure ledger): a taint row
|
|
11
|
+
carries an opaque conversation key, an opaque subject contact id, an opaque
|
|
12
|
+
fact ref, an inference kind, and the subject's normalized DISPLAY NAMES —
|
|
13
|
+
which are, by the M1 mutual-knowledge gate, names the reader already knows.
|
|
14
|
+
Fact TEXT never enters this table; a leak of the registry reveals that a
|
|
15
|
+
prior about someone was injected somewhere, never what it said.
|
|
16
|
+
|
|
17
|
+
Hot-path economics: ``any_active()`` is the guard's first question every
|
|
18
|
+
turn, so it is answered from an in-memory latest-expiry watermark (a clock
|
|
19
|
+
comparison, no DB hit) whenever no taint could possibly be live. The
|
|
20
|
+
watermark is loaded from SQLite at startup, so taints survive a restart.
|
|
21
|
+
|
|
22
|
+
Fail-closed direction: a taint is PROTECTION, so errors lean toward keeping
|
|
23
|
+
it — malformed TTL config reads as the default, and expiry is judged
|
|
24
|
+
against wall-clock timestamps written at register time.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import json
|
|
30
|
+
import logging
|
|
31
|
+
import os
|
|
32
|
+
import re
|
|
33
|
+
import sqlite3
|
|
34
|
+
import threading
|
|
35
|
+
import time
|
|
36
|
+
import uuid
|
|
37
|
+
from typing import Any, Dict, List, Optional
|
|
38
|
+
|
|
39
|
+
from apsimo.gate.context_provenance import normalize_entity
|
|
40
|
+
from apsimo.tom.tom2 import INFERENCE_KINDS, _validate_ref
|
|
41
|
+
|
|
42
|
+
logger = logging.getLogger(__name__)
|
|
43
|
+
|
|
44
|
+
DEFAULT_TTL_SECS = 900.0
|
|
45
|
+
|
|
46
|
+
#: Opaque conversation keys / contact ids: compact, no whitespace — prose is
|
|
47
|
+
#: refused so message or fact text cannot be smuggled through these fields.
|
|
48
|
+
_KEY_RE = re.compile(r"^[A-Za-z0-9_.:+@-]{1,128}$")
|
|
49
|
+
|
|
50
|
+
_MAX_NAMES = 8
|
|
51
|
+
_MAX_NAME_LEN = 80
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def taint_ttl_secs() -> float:
|
|
55
|
+
"""COLONY_TOM2_TAINT_TTL_SECS (default 900): how long a registered
|
|
56
|
+
injection stays hot for the egress net. Malformed values read as the
|
|
57
|
+
default (a taint is protection; misconfiguration must not shorten it);
|
|
58
|
+
values <= 0 clamp to the default for the same reason."""
|
|
59
|
+
raw = os.environ.get("COLONY_TOM2_TAINT_TTL_SECS")
|
|
60
|
+
if raw is None or not str(raw).strip():
|
|
61
|
+
return DEFAULT_TTL_SECS
|
|
62
|
+
try:
|
|
63
|
+
v = float(str(raw).strip())
|
|
64
|
+
except (TypeError, ValueError):
|
|
65
|
+
logger.warning("COLONY_TOM2_TAINT_TTL_SECS=%r is malformed — using "
|
|
66
|
+
"the default %ss", raw, DEFAULT_TTL_SECS)
|
|
67
|
+
return DEFAULT_TTL_SECS
|
|
68
|
+
return v if v > 0 else DEFAULT_TTL_SECS
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _validate_key(value: Any, what: str) -> str:
|
|
72
|
+
value = str(value or "").strip()
|
|
73
|
+
if not _KEY_RE.match(value):
|
|
74
|
+
raise ValueError(f"taint {what} {value[:40]!r} is not an opaque id "
|
|
75
|
+
"(refs-not-content invariant)")
|
|
76
|
+
return value
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _clean_names(names: Any) -> List[str]:
|
|
80
|
+
"""Normalize subject display names (normalize_entity), dedupe, cap."""
|
|
81
|
+
out: List[str] = []
|
|
82
|
+
seen = set()
|
|
83
|
+
for raw in list(names or [])[: _MAX_NAMES * 2]:
|
|
84
|
+
n = normalize_entity(str(raw or ""))[:_MAX_NAME_LEN]
|
|
85
|
+
if len(n) >= 2 and n not in seen:
|
|
86
|
+
seen.add(n)
|
|
87
|
+
out.append(n)
|
|
88
|
+
if len(out) >= _MAX_NAMES:
|
|
89
|
+
break
|
|
90
|
+
return out
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class TaintRegistry:
|
|
94
|
+
"""SQLite-backed TTL registry of live level-2 injections."""
|
|
95
|
+
|
|
96
|
+
def __init__(self, db_path: Optional[str] = None) -> None:
|
|
97
|
+
self._lock = threading.RLock()
|
|
98
|
+
self._conn = sqlite3.connect(db_path or ":memory:",
|
|
99
|
+
check_same_thread=False)
|
|
100
|
+
self._conn.row_factory = sqlite3.Row
|
|
101
|
+
with self._lock:
|
|
102
|
+
self._conn.execute("""
|
|
103
|
+
CREATE TABLE IF NOT EXISTS tom2_taints (
|
|
104
|
+
id TEXT PRIMARY KEY,
|
|
105
|
+
conversation_key TEXT NOT NULL,
|
|
106
|
+
subject_contact_id TEXT NOT NULL,
|
|
107
|
+
subject_names TEXT NOT NULL DEFAULT '[]',
|
|
108
|
+
fact_ref TEXT NOT NULL,
|
|
109
|
+
kind TEXT NOT NULL,
|
|
110
|
+
created_at REAL NOT NULL,
|
|
111
|
+
expires_at REAL NOT NULL
|
|
112
|
+
)""")
|
|
113
|
+
self._conn.execute(
|
|
114
|
+
"CREATE INDEX IF NOT EXISTS idx_tom2_taints_conv "
|
|
115
|
+
"ON tom2_taints(conversation_key, expires_at)")
|
|
116
|
+
self._conn.commit()
|
|
117
|
+
# In-memory watermark: the hot path answers "no taints" from a
|
|
118
|
+
# clock comparison. Persisted taints re-arm it across restarts.
|
|
119
|
+
row = self._conn.execute(
|
|
120
|
+
"SELECT MAX(expires_at) m FROM tom2_taints").fetchone()
|
|
121
|
+
self._latest_expiry: float = float(row["m"] or 0.0)
|
|
122
|
+
|
|
123
|
+
# -- writes -------------------------------------------------------------
|
|
124
|
+
def register(self, conversation_key: str, subject_contact_id: str,
|
|
125
|
+
subject_names: Optional[List[str]] = None,
|
|
126
|
+
fact_ref: str = "", kind: str = "unaware_of",
|
|
127
|
+
ttl_seconds: Optional[float] = None) -> Dict[str, Any]:
|
|
128
|
+
"""Record one live injection. Raises on any privacy-pin violation
|
|
129
|
+
(prose in an opaque field, unknown kind) — never best-effort."""
|
|
130
|
+
if kind not in INFERENCE_KINDS:
|
|
131
|
+
raise ValueError(f"unknown taint kind {kind!r}")
|
|
132
|
+
ttl = float(ttl_seconds) if ttl_seconds is not None\
|
|
133
|
+
else taint_ttl_secs()
|
|
134
|
+
if ttl <= 0:
|
|
135
|
+
ttl = taint_ttl_secs()
|
|
136
|
+
now = time.time()
|
|
137
|
+
row = {
|
|
138
|
+
"id": str(uuid.uuid4()),
|
|
139
|
+
"conversation_key": _validate_key(conversation_key,
|
|
140
|
+
"conversation key"),
|
|
141
|
+
"subject_contact_id": _validate_key(subject_contact_id,
|
|
142
|
+
"subject id"),
|
|
143
|
+
"subject_names": _clean_names(subject_names),
|
|
144
|
+
"fact_ref": _validate_ref(fact_ref),
|
|
145
|
+
"kind": kind,
|
|
146
|
+
"created_at": now,
|
|
147
|
+
"expires_at": now + ttl,
|
|
148
|
+
}
|
|
149
|
+
with self._lock:
|
|
150
|
+
self._conn.execute(
|
|
151
|
+
"INSERT INTO tom2_taints (id, conversation_key, "
|
|
152
|
+
"subject_contact_id, subject_names, fact_ref, kind, "
|
|
153
|
+
"created_at, expires_at) VALUES (?,?,?,?,?,?,?,?)",
|
|
154
|
+
(row["id"], row["conversation_key"],
|
|
155
|
+
row["subject_contact_id"], json.dumps(row["subject_names"]),
|
|
156
|
+
row["fact_ref"], row["kind"], row["created_at"],
|
|
157
|
+
row["expires_at"]))
|
|
158
|
+
self._conn.commit()
|
|
159
|
+
self._latest_expiry = max(self._latest_expiry, row["expires_at"])
|
|
160
|
+
return row
|
|
161
|
+
|
|
162
|
+
def purge_expired(self) -> int:
|
|
163
|
+
"""Drop expired rows (housekeeping; reads already exclude them)."""
|
|
164
|
+
with self._lock:
|
|
165
|
+
cur = self._conn.execute(
|
|
166
|
+
"DELETE FROM tom2_taints WHERE expires_at <= ?",
|
|
167
|
+
(time.time(),))
|
|
168
|
+
self._conn.commit()
|
|
169
|
+
return cur.rowcount
|
|
170
|
+
|
|
171
|
+
# -- reads --------------------------------------------------------------
|
|
172
|
+
@staticmethod
|
|
173
|
+
def _to_dict(row: Any) -> Dict[str, Any]:
|
|
174
|
+
d = dict(row)
|
|
175
|
+
try:
|
|
176
|
+
d["subject_names"] = json.loads(d.get("subject_names") or "[]")
|
|
177
|
+
except Exception:
|
|
178
|
+
d["subject_names"] = []
|
|
179
|
+
return d
|
|
180
|
+
|
|
181
|
+
def any_active(self) -> bool:
|
|
182
|
+
"""Is ANY taint live right now? Answered from the in-memory
|
|
183
|
+
watermark — zero DB cost on the (overwhelmingly common) no-taint
|
|
184
|
+
turn, which is what keeps the egress check inert for free."""
|
|
185
|
+
with self._lock:
|
|
186
|
+
return time.time() < self._latest_expiry
|
|
187
|
+
|
|
188
|
+
def active_for(self, conversation_key: str) -> List[Dict[str, Any]]:
|
|
189
|
+
"""Live taints registered against THIS conversation."""
|
|
190
|
+
if not self.any_active():
|
|
191
|
+
return []
|
|
192
|
+
with self._lock:
|
|
193
|
+
rows = self._conn.execute(
|
|
194
|
+
"SELECT * FROM tom2_taints WHERE conversation_key = ? "
|
|
195
|
+
"AND expires_at > ? ORDER BY expires_at DESC",
|
|
196
|
+
(str(conversation_key or ""), time.time())).fetchall()
|
|
197
|
+
return [self._to_dict(r) for r in rows]
|
|
198
|
+
|
|
199
|
+
def all_active(self) -> List[Dict[str, Any]]:
|
|
200
|
+
"""Every live taint, any conversation — the egress net checks the
|
|
201
|
+
reply against ALL of them (a prior injected in one conversation must
|
|
202
|
+
not be voiced anywhere while it is hot)."""
|
|
203
|
+
if not self.any_active():
|
|
204
|
+
return []
|
|
205
|
+
with self._lock:
|
|
206
|
+
rows = self._conn.execute(
|
|
207
|
+
"SELECT * FROM tom2_taints WHERE expires_at > ? "
|
|
208
|
+
"ORDER BY expires_at DESC", (time.time(),)).fetchall()
|
|
209
|
+
return [self._to_dict(r) for r in rows]
|
|
210
|
+
|
|
211
|
+
def counts(self) -> Dict[str, Any]:
|
|
212
|
+
"""Aggregate observability (numbers only)."""
|
|
213
|
+
now = time.time()
|
|
214
|
+
with self._lock:
|
|
215
|
+
total = self._conn.execute(
|
|
216
|
+
"SELECT COUNT(*) n FROM tom2_taints").fetchone()["n"]
|
|
217
|
+
active = self._conn.execute(
|
|
218
|
+
"SELECT COUNT(*) n FROM tom2_taints WHERE expires_at > ?",
|
|
219
|
+
(now,)).fetchone()["n"]
|
|
220
|
+
return {"rows": int(total), "active": int(active)}
|
|
221
|
+
|
|
222
|
+
def close(self) -> None:
|
|
223
|
+
try:
|
|
224
|
+
self._conn.close()
|
|
225
|
+
except Exception:
|
|
226
|
+
pass
|
apsimo/genesis.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"colony_id": "31a441ea-0191-4bfb-a87f-98a6703a6db3",
|
|
3
|
+
"public_key_ed25519": "341065fd6cd26ca501c5786ed1517eedc448fec60aeaea8d047d07bf1a9cc351",
|
|
4
|
+
"alias": "genesis",
|
|
5
|
+
"genesis_version": 1,
|
|
6
|
+
"signed_at": "2026-04-20T17:04:26.242399+00:00",
|
|
7
|
+
"description": "The original Colony — trust anchor for the network",
|
|
8
|
+
"signature": "f695be354a0f8534ea178c1c8cd01d335f0cfb6ce72ed4d5db2a5b5f812e9546ccde8edd17683c8b5b55bf263d29a9b77bc8ac7b34b88642f4278022ec7da803"
|
|
9
|
+
}
|
apsimo/goals/__init__.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Legacy goal records and optional planner compatibility.
|
|
2
|
+
|
|
3
|
+
New execution belongs to native runtime tasks and canonical commitments.
|
|
4
|
+
The default GoalEngine stores accepted goals without an execution backend.
|
|
5
|
+
Planner exports remain for existing readers and stored-goal migrations;
|
|
6
|
+
their presence does not establish live execution.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from importlib import import_module
|
|
10
|
+
|
|
11
|
+
from .config import GoalEngineConfig
|
|
12
|
+
from .models import (
|
|
13
|
+
Goal,
|
|
14
|
+
GoalDAG,
|
|
15
|
+
GoalOutcome,
|
|
16
|
+
GoalPriority,
|
|
17
|
+
GoalSource,
|
|
18
|
+
GoalStatus,
|
|
19
|
+
GoalSummary,
|
|
20
|
+
GoalTransitionRecord,
|
|
21
|
+
Subtask,
|
|
22
|
+
SubtaskStatus,
|
|
23
|
+
)
|
|
24
|
+
from .store import GoalNotFoundError, GoalStore
|
|
25
|
+
|
|
26
|
+
# A reader importing goals.models/store must not load the optional planner.
|
|
27
|
+
# Preserve public exports for explicitly configured legacy callers, including
|
|
28
|
+
# class identity and pickle module names, without constructing another facade.
|
|
29
|
+
_PLANNER_EXPORTS = {
|
|
30
|
+
name: module for module, names in (
|
|
31
|
+
('engine', ('GoalEngine',)),
|
|
32
|
+
('decomposer', ('DecompositionTemplate', 'GoalDecomposer', 'SubtaskSpec')),
|
|
33
|
+
('inference', ('ConversationMessage', 'GoalDeduplicator', 'GoalInferencePipeline',
|
|
34
|
+
'GoalSimilarity', 'InferenceCandidate', 'IntentSignal')),
|
|
35
|
+
('priority', ('GoalProgressTracker', 'GoalPriorityScorer', 'PriorityScore',
|
|
36
|
+
'UserPreferenceProfile')),
|
|
37
|
+
('queue_bridge', ('GoalQueueBridge', 'InMemoryQueueBackend')),
|
|
38
|
+
('replan', ('FailureAnalysis', 'FailureClass', 'ReplanEngine', 'ReplanResult',
|
|
39
|
+
'ReplanStrategy')),
|
|
40
|
+
) for name in names
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def __getattr__(name):
|
|
45
|
+
module = _PLANNER_EXPORTS.get(name)
|
|
46
|
+
if module is None:
|
|
47
|
+
raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
|
|
48
|
+
value = getattr(import_module('.' + module, __name__), name)
|
|
49
|
+
globals()[name] = value
|
|
50
|
+
return value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def __dir__():
|
|
54
|
+
return sorted(set(globals()) | set(__all__))
|
|
55
|
+
|
|
56
|
+
__all__ = [
|
|
57
|
+
# Config
|
|
58
|
+
"GoalEngineConfig",
|
|
59
|
+
# Engine
|
|
60
|
+
"GoalEngine",
|
|
61
|
+
# Models
|
|
62
|
+
"Goal",
|
|
63
|
+
"GoalDAG",
|
|
64
|
+
"GoalOutcome",
|
|
65
|
+
"GoalPriority",
|
|
66
|
+
"GoalSource",
|
|
67
|
+
"GoalStatus",
|
|
68
|
+
"GoalSummary",
|
|
69
|
+
"GoalTransitionRecord",
|
|
70
|
+
"Subtask",
|
|
71
|
+
"SubtaskStatus",
|
|
72
|
+
# Inference
|
|
73
|
+
"ConversationMessage",
|
|
74
|
+
"GoalDeduplicator",
|
|
75
|
+
"GoalInferencePipeline",
|
|
76
|
+
"GoalSimilarity",
|
|
77
|
+
"InferenceCandidate",
|
|
78
|
+
"IntentSignal",
|
|
79
|
+
# Decomposer
|
|
80
|
+
"DecompositionTemplate",
|
|
81
|
+
"GoalDecomposer",
|
|
82
|
+
"SubtaskSpec",
|
|
83
|
+
# Priority / Progress
|
|
84
|
+
"GoalProgressTracker",
|
|
85
|
+
"GoalPriorityScorer",
|
|
86
|
+
"PriorityScore",
|
|
87
|
+
"UserPreferenceProfile",
|
|
88
|
+
# Queue Bridge
|
|
89
|
+
"GoalQueueBridge",
|
|
90
|
+
"InMemoryQueueBackend",
|
|
91
|
+
# Replan
|
|
92
|
+
"FailureAnalysis",
|
|
93
|
+
"FailureClass",
|
|
94
|
+
"ReplanEngine",
|
|
95
|
+
"ReplanResult",
|
|
96
|
+
"ReplanStrategy",
|
|
97
|
+
# Store
|
|
98
|
+
"GoalNotFoundError",
|
|
99
|
+
"GoalStore",
|
|
100
|
+
]
|
apsimo/goals/config.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Configuration for the Colony Goal Engine."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class GoalEngineConfig:
|
|
11
|
+
"""Configuration for the Colony Goal Engine.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
enabled: Whether the goal engine is active.
|
|
15
|
+
auto_accept_threshold: Confidence threshold for auto-accepting inferred goals (0.0–1.0).
|
|
16
|
+
max_replans: Maximum replan attempts per goal before escalating to user.
|
|
17
|
+
max_subtasks: Maximum subtasks per goal DAG.
|
|
18
|
+
max_depth: Maximum DAG depth.
|
|
19
|
+
max_blocked_hours: Hours before a blocked goal is escalated to the user.
|
|
20
|
+
inference_enabled: Whether to run goal inference on conversation messages.
|
|
21
|
+
inference_lm_threshold: Confidence below which LLM inference pass is triggered.
|
|
22
|
+
proposal_min_interval: Minimum seconds between goal proposals to avoid noise.
|
|
23
|
+
retention_days: Days to retain completed/abandoned goals.
|
|
24
|
+
telemetry_enabled: Whether to emit goal telemetry to the MetaLearner.
|
|
25
|
+
db_path: Path to SQLite database (defaults to in-memory for tests).
|
|
26
|
+
"""
|
|
27
|
+
enabled: bool = True
|
|
28
|
+
auto_accept_threshold: float = 0.85
|
|
29
|
+
max_replans: int = 5
|
|
30
|
+
max_subtasks: int = 50
|
|
31
|
+
max_depth: int = 5
|
|
32
|
+
max_blocked_hours: float = 24.0
|
|
33
|
+
inference_enabled: bool = True
|
|
34
|
+
inference_lm_threshold: float = 0.70
|
|
35
|
+
proposal_min_interval: float = 300.0 # 5 minutes
|
|
36
|
+
retention_days: int = 90
|
|
37
|
+
telemetry_enabled: bool = True
|
|
38
|
+
db_path: Optional[str] = None # None → in-memory SQLite
|