shellbrain 0.1.23__tar.gz → 0.1.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shellbrain-0.1.23 → shellbrain-0.1.25}/PKG-INFO +1 -1
- shellbrain-0.1.25/app/boot/migrations.py +115 -0
- shellbrain-0.1.25/app/core/contracts/concepts.py +212 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/contracts/requests.py +40 -1
- shellbrain-0.1.25/app/core/entities/concepts.py +302 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/telemetry.py +4 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/repos.py +75 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/unit_of_work.py +2 -0
- shellbrain-0.1.25/app/core/use_cases/manage_concepts.py +460 -0
- shellbrain-0.1.25/app/core/use_cases/read_concepts.py +435 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/read_memory.py +7 -0
- shellbrain-0.1.25/app/migrations/versions/20260421_0013_concept_context_graph.py +220 -0
- shellbrain-0.1.25/app/migrations/versions/20260422_0014_concept_read_telemetry.py +36 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/init.py +5 -2
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/cli/handlers.py +52 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/cli/hydration.py +8 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/cli/main.py +44 -3
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/cli/schema_validation.py +18 -0
- shellbrain-0.1.25/app/periphery/db/models/concepts.py +247 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/registry.py +2 -1
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/telemetry.py +4 -0
- shellbrain-0.1.25/app/periphery/db/repos/relational/concepts_repo.py +774 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/uow.py +2 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/telemetry/operation_summary.py +47 -1
- {shellbrain-0.1.23 → shellbrain-0.1.25}/pyproject.toml +1 -1
- {shellbrain-0.1.23 → shellbrain-0.1.25}/shellbrain.egg-info/PKG-INFO +1 -1
- {shellbrain-0.1.23 → shellbrain-0.1.25}/shellbrain.egg-info/SOURCES.txt +8 -0
- shellbrain-0.1.23/app/boot/migrations.py +0 -61
- {shellbrain-0.1.23 → shellbrain-0.1.25}/README.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/__main__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/_dsn_resolution.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/admin_db.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/config.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/create_policy.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/db.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/embeddings.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/home.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/read_policy.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/repos.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/retrieval.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/thresholds.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/update_policy.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/boot/use_cases.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/defaults/create_policy.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/defaults/read_policy.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/defaults/runtime.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/defaults/thresholds.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/defaults/update_policy.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/config/loader.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/contracts/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/contracts/errors.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/contracts/responses.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/associations.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/episodes.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/evidence.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/facts.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/guidance.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/identity.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/memory.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/runtime_context.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/session_state.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/entities/utility.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/clock.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/config.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/embeddings.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/idgen.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/retrieval.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/interfaces/session_state_store.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/_shared/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/_shared/executor.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/_shared/side_effects.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/create_policy/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/create_policy/pipeline.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/bm25.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/context_pack_builder.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/expansion.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/fusion_rrf.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/lexical_query.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/pipeline.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/scoring.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/read_policy/seed_retrieval.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/update_policy/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/policies/update_policy/pipeline.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/build_guidance.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/create_memory.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/manage_session_state.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/record_episode_sync_telemetry.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/record_model_usage_telemetry.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/record_operation_telemetry.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/sync_episode.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/core/use_cases/update_memory.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/env.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260226_0001_initial_schema.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260312_0002_add_hard_invariants.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260312_0003_drop_create_confidence.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260313_0004_episode_sync_hardening.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260313_0005_evidence_episode_event_refs.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260318_0006_usage_telemetry_schema.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260319_0007_identity_session_guidance.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260320_0008_instance_metadata_and_backup_safety.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260410_0009_frontier_memory_family.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260414_0010_model_usage_telemetry.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260414_0011_usage_problem_tokens_multi_solution_metrics.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/20260415_0012_read_pack_cost_and_read_roi.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/migrations/versions/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/claude/CLAUDE.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/claude/skills/shellbrain-session-start/SKILL.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/claude/skills/shellbrain-usage-review/SKILL.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/AGENTS.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/SKILL.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/agents/openai.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/assets/shellbrain-large.svg +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/assets/shellbrain-small.svg +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/assets/shellbrain_logo.png +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/references/request-shapes.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-session-start/references/session-workflow.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-usage-review/SKILL.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-usage-review/agents/openai.yaml +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-usage-review/assets/shellbrain-small.svg +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/codex/shellbrain-usage-review/assets/shellbrain_logo.png +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/cursor/skills/shellbrain-session-start/SKILL.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/onboarding_assets/cursor/skills/shellbrain-usage-review/SKILL.md +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/agent_behavior_analysis.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/analytics.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/analytics_diagnostics.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/analytics_queries.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/backup.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/destructive_guard.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/doctor.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/external_runtime.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/init_errors.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/instance_guard.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/machine_state.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/managed_runtime.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/model_usage_backfill.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/privileges.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/repo_state.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/restore.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/storage_setup.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/admin/upgrade.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/cli/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/cli/presenter_json.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/engine.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/associations.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/episodes.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/evidence.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/experiences.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/instance_metadata.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/memories.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/metadata.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/utility.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/models/views.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/associations_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/episodes_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/evidence_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/experiences_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/memories_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/read_policy_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/telemetry_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/relational/utility_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/semantic/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/semantic/keyword_retrieval_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/repos/semantic/semantic_retrieval_repo.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/db/session.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/embeddings/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/embeddings/local_provider.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/embeddings/query_vector_search.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/claude_code.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/codex.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/cursor.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/launcher.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/model_usage.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/normalization.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/poller.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/poller_lock.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/source_discovery.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/episodes/tool_filter.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/claude_hook_install.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/claude_runtime.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/codex_runtime.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/compatibility.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/cursor_statusline.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/identity/resolver.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/metrics/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/metrics/artifacts.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/metrics/browser.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/metrics/queries.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/metrics/render_html.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/metrics/service.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/onboarding/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/onboarding/host_assets.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/session_state/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/session_state/file_store.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/telemetry/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/telemetry/session_selection.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/telemetry/sync_summary.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/validation/__init__.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/validation/integrity_validation.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/app/periphery/validation/semantic_validation.py +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/setup.cfg +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/shellbrain.egg-info/dependency_links.txt +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/shellbrain.egg-info/entry_points.txt +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/shellbrain.egg-info/requires.txt +0 -0
- {shellbrain-0.1.23 → shellbrain-0.1.25}/shellbrain.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Packaged Alembic bootstrap helpers for installed-shellbrain database migrations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib.resources import as_file, files
|
|
6
|
+
import importlib.metadata
|
|
7
|
+
|
|
8
|
+
from alembic import command
|
|
9
|
+
from alembic.config import Config
|
|
10
|
+
from alembic.script import ScriptDirectory
|
|
11
|
+
from alembic.script.revision import ResolutionError
|
|
12
|
+
|
|
13
|
+
from app.boot.admin_db import get_admin_db_dsn, get_backup_dir, get_backup_mirror_dir, get_instance_mode_default
|
|
14
|
+
from app.boot.db import get_optional_db_dsn
|
|
15
|
+
from app.periphery.admin.destructive_guard import backup_and_verify_before_destructive_action
|
|
16
|
+
from app.periphery.admin.instance_guard import ensure_instance_metadata, fetch_instance_metadata
|
|
17
|
+
from app.periphery.admin.privileges import reconcile_app_role_privileges
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DatabaseRevisionAheadOfInstalledPackageError(RuntimeError):
|
|
21
|
+
"""Raised when the target database revision is newer than the installed package knows about."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def upgrade_database(revision: str = "head") -> None:
|
|
25
|
+
"""Apply packaged Alembic migrations to the configured database."""
|
|
26
|
+
|
|
27
|
+
config = Config()
|
|
28
|
+
admin_dsn = get_admin_db_dsn()
|
|
29
|
+
with as_file(files("app").joinpath("migrations")) as migrations_path:
|
|
30
|
+
config.set_main_option("script_location", str(migrations_path))
|
|
31
|
+
script = ScriptDirectory.from_config(config)
|
|
32
|
+
if _database_has_shellbrain_objects(admin_dsn):
|
|
33
|
+
_assert_database_revision_is_known(admin_dsn=admin_dsn, script=script)
|
|
34
|
+
backup_and_verify_before_destructive_action(
|
|
35
|
+
admin_dsn=admin_dsn,
|
|
36
|
+
backup_root=get_backup_dir(),
|
|
37
|
+
mirror_root=get_backup_mirror_dir(),
|
|
38
|
+
)
|
|
39
|
+
config.set_main_option("sqlalchemy.url", admin_dsn)
|
|
40
|
+
command.upgrade(config, revision)
|
|
41
|
+
if fetch_instance_metadata(admin_dsn) is None:
|
|
42
|
+
ensure_instance_metadata(
|
|
43
|
+
admin_dsn,
|
|
44
|
+
instance_mode=get_instance_mode_default(),
|
|
45
|
+
created_by="app.admin.migrate",
|
|
46
|
+
notes="Stamped by packaged migration runner.",
|
|
47
|
+
)
|
|
48
|
+
app_dsn = get_optional_db_dsn()
|
|
49
|
+
if app_dsn:
|
|
50
|
+
reconcile_app_role_privileges(admin_dsn=admin_dsn, app_dsn=app_dsn)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _database_has_shellbrain_objects(admin_dsn: str) -> bool:
|
|
54
|
+
"""Return whether the target database already contains Shellbrain-managed tables."""
|
|
55
|
+
|
|
56
|
+
import psycopg
|
|
57
|
+
|
|
58
|
+
with psycopg.connect(admin_dsn.replace("+psycopg", "")) as conn:
|
|
59
|
+
with conn.cursor() as cur:
|
|
60
|
+
cur.execute(
|
|
61
|
+
"""
|
|
62
|
+
SELECT EXISTS (
|
|
63
|
+
SELECT 1
|
|
64
|
+
FROM information_schema.tables
|
|
65
|
+
WHERE table_schema = 'public'
|
|
66
|
+
AND table_name IN ('memories', 'episodes', 'episode_events', 'operation_invocations')
|
|
67
|
+
)
|
|
68
|
+
"""
|
|
69
|
+
)
|
|
70
|
+
return bool(cur.fetchone()[0])
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _assert_database_revision_is_known(*, admin_dsn: str, script: ScriptDirectory) -> None:
|
|
74
|
+
"""Fail early with a user-facing error when the database revision is newer than this package."""
|
|
75
|
+
|
|
76
|
+
current_revision = _fetch_database_revision(admin_dsn)
|
|
77
|
+
if current_revision is None:
|
|
78
|
+
return
|
|
79
|
+
try:
|
|
80
|
+
script.get_revision(current_revision)
|
|
81
|
+
except ResolutionError as exc:
|
|
82
|
+
installed_version = _installed_shellbrain_version()
|
|
83
|
+
raise DatabaseRevisionAheadOfInstalledPackageError(
|
|
84
|
+
"Installed Shellbrain package "
|
|
85
|
+
f"({installed_version}) cannot manage database revision {current_revision}. "
|
|
86
|
+
"This database was likely migrated by a newer Shellbrain release than the one currently installed. "
|
|
87
|
+
"Upgrade Shellbrain to a build that includes this revision, then rerun `shellbrain init` or "
|
|
88
|
+
"`shellbrain admin migrate`."
|
|
89
|
+
) from exc
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _fetch_database_revision(admin_dsn: str) -> str | None:
|
|
93
|
+
"""Return the current alembic revision when present."""
|
|
94
|
+
|
|
95
|
+
import psycopg
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
with psycopg.connect(admin_dsn.replace("+psycopg", "")) as conn:
|
|
99
|
+
with conn.cursor() as cur:
|
|
100
|
+
cur.execute("SELECT version_num FROM alembic_version")
|
|
101
|
+
row = cur.fetchone()
|
|
102
|
+
except psycopg.Error:
|
|
103
|
+
return None
|
|
104
|
+
if row is None or row[0] is None:
|
|
105
|
+
return None
|
|
106
|
+
return str(row[0])
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _installed_shellbrain_version() -> str:
|
|
110
|
+
"""Return the installed Shellbrain package version when available."""
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
return importlib.metadata.version("shellbrain")
|
|
114
|
+
except importlib.metadata.PackageNotFoundError:
|
|
115
|
+
return "dev"
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""Strict request contracts for the concept-context graph endpoint."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Annotated, Any, Literal
|
|
7
|
+
|
|
8
|
+
from pydantic import Field, model_validator
|
|
9
|
+
|
|
10
|
+
from app.core.contracts.requests import StrictBaseModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
ConceptKindValue = Literal["domain", "capability", "process", "entity", "rule", "component"]
|
|
14
|
+
ConceptStatusValue = Literal["active", "deprecated", "archived"]
|
|
15
|
+
ConceptRelationPredicateValue = Literal["contains", "involves", "precedes", "constrains", "depends_on"]
|
|
16
|
+
ConceptClaimTypeValue = Literal["definition", "behavior", "invariant", "failure_mode", "usage_note", "open_question"]
|
|
17
|
+
AnchorKindValue = Literal[
|
|
18
|
+
"file",
|
|
19
|
+
"symbol",
|
|
20
|
+
"line_range",
|
|
21
|
+
"api_route",
|
|
22
|
+
"db_table",
|
|
23
|
+
"schema",
|
|
24
|
+
"config_key",
|
|
25
|
+
"test",
|
|
26
|
+
"metric",
|
|
27
|
+
"log",
|
|
28
|
+
"doc",
|
|
29
|
+
"commit",
|
|
30
|
+
"memory",
|
|
31
|
+
]
|
|
32
|
+
ConceptGroundingRoleValue = Literal[
|
|
33
|
+
"implementation",
|
|
34
|
+
"entrypoint",
|
|
35
|
+
"storage",
|
|
36
|
+
"configuration",
|
|
37
|
+
"test",
|
|
38
|
+
"observability",
|
|
39
|
+
"documentation",
|
|
40
|
+
]
|
|
41
|
+
ConceptMemoryLinkRoleValue = Literal[
|
|
42
|
+
"example_of",
|
|
43
|
+
"solution_for",
|
|
44
|
+
"failed_tactic_for",
|
|
45
|
+
"changed",
|
|
46
|
+
"validated",
|
|
47
|
+
"contradicted",
|
|
48
|
+
"warned_about",
|
|
49
|
+
]
|
|
50
|
+
ConceptEvidenceKindValue = Literal["anchor", "memory", "commit", "transcript", "test", "manual"]
|
|
51
|
+
ConceptSourceKindValue = Literal[
|
|
52
|
+
"commit",
|
|
53
|
+
"file_hash",
|
|
54
|
+
"symbol_hash",
|
|
55
|
+
"memory",
|
|
56
|
+
"transcript_event",
|
|
57
|
+
"manual",
|
|
58
|
+
"doc",
|
|
59
|
+
"runtime_trace",
|
|
60
|
+
]
|
|
61
|
+
ConceptCreatedByValue = Literal["worker", "librarian", "manual", "import"]
|
|
62
|
+
ConceptShowIncludeValue = Literal["claims", "relations", "groundings", "memory_links", "preview_concept"]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ConceptEvidencePayload(StrictBaseModel):
|
|
66
|
+
"""Evidence supplied inline with one truth-bearing concept action."""
|
|
67
|
+
|
|
68
|
+
kind: ConceptEvidenceKindValue
|
|
69
|
+
anchor_id: str | None = None
|
|
70
|
+
memory_id: str | None = None
|
|
71
|
+
commit_ref: str | None = None
|
|
72
|
+
transcript_ref: str | None = None
|
|
73
|
+
note: str | None = None
|
|
74
|
+
|
|
75
|
+
@model_validator(mode="after")
|
|
76
|
+
def _validate_required_reference(self) -> "ConceptEvidencePayload":
|
|
77
|
+
"""Require the reference field implied by the evidence kind."""
|
|
78
|
+
|
|
79
|
+
if self.kind == "anchor" and not self.anchor_id:
|
|
80
|
+
raise ValueError("anchor evidence requires anchor_id")
|
|
81
|
+
if self.kind == "memory" and not self.memory_id:
|
|
82
|
+
raise ValueError("memory evidence requires memory_id")
|
|
83
|
+
if self.kind == "commit" and not self.commit_ref:
|
|
84
|
+
raise ValueError("commit evidence requires commit_ref")
|
|
85
|
+
if self.kind == "transcript" and not self.transcript_ref:
|
|
86
|
+
raise ValueError("transcript evidence requires transcript_ref")
|
|
87
|
+
if self.kind in {"manual", "test"} and not self.note:
|
|
88
|
+
raise ValueError(f"{self.kind} evidence requires note")
|
|
89
|
+
return self
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ConceptLifecycleActionFields(StrictBaseModel):
|
|
93
|
+
"""Shared optional lifecycle fields on concept write actions."""
|
|
94
|
+
|
|
95
|
+
confidence: float = Field(default=0.5, ge=0.0, le=1.0)
|
|
96
|
+
observed_at: datetime | None = None
|
|
97
|
+
validated_at: datetime | None = None
|
|
98
|
+
source_kind: ConceptSourceKindValue | None = None
|
|
99
|
+
source_ref: str | None = None
|
|
100
|
+
created_by: ConceptCreatedByValue = "manual"
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class UpsertConceptAction(StrictBaseModel):
|
|
104
|
+
"""Create or update a concept container and aliases."""
|
|
105
|
+
|
|
106
|
+
type: Literal["upsert_concept"]
|
|
107
|
+
slug: str = Field(min_length=1)
|
|
108
|
+
name: str = Field(min_length=1)
|
|
109
|
+
kind: ConceptKindValue
|
|
110
|
+
status: ConceptStatusValue = "active"
|
|
111
|
+
scope_note: str | None = None
|
|
112
|
+
aliases: list[str] = Field(default_factory=list)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class AddRelationAction(ConceptLifecycleActionFields):
|
|
116
|
+
"""Create an evidence-backed concept relation."""
|
|
117
|
+
|
|
118
|
+
type: Literal["add_relation"]
|
|
119
|
+
subject: str = Field(min_length=1)
|
|
120
|
+
predicate: ConceptRelationPredicateValue
|
|
121
|
+
object: str = Field(min_length=1)
|
|
122
|
+
evidence: list[ConceptEvidencePayload] = Field(min_length=1)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class AddClaimAction(ConceptLifecycleActionFields):
|
|
126
|
+
"""Create an evidence-backed concept claim."""
|
|
127
|
+
|
|
128
|
+
type: Literal["add_claim"]
|
|
129
|
+
concept: str = Field(min_length=1)
|
|
130
|
+
claim_type: ConceptClaimTypeValue
|
|
131
|
+
text: str = Field(min_length=1)
|
|
132
|
+
evidence: list[ConceptEvidencePayload] = Field(min_length=1)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class UpsertAnchorAction(StrictBaseModel):
|
|
136
|
+
"""Create or fetch a real-world anchor by canonical locator."""
|
|
137
|
+
|
|
138
|
+
type: Literal["upsert_anchor"]
|
|
139
|
+
kind: AnchorKindValue
|
|
140
|
+
locator: dict[str, Any] = Field(default_factory=dict)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class AnchorSelector(StrictBaseModel):
|
|
144
|
+
"""Reference an existing anchor or define an inline anchor to upsert."""
|
|
145
|
+
|
|
146
|
+
id: str | None = None
|
|
147
|
+
kind: AnchorKindValue | None = None
|
|
148
|
+
locator: dict[str, Any] | None = None
|
|
149
|
+
|
|
150
|
+
@model_validator(mode="after")
|
|
151
|
+
def _validate_selector(self) -> "AnchorSelector":
|
|
152
|
+
"""Require either an id or a complete inline anchor."""
|
|
153
|
+
|
|
154
|
+
has_inline = self.kind is not None and self.locator is not None
|
|
155
|
+
if not self.id and not has_inline:
|
|
156
|
+
raise ValueError("anchor requires id or kind+locator")
|
|
157
|
+
if self.id and (self.kind is not None or self.locator is not None):
|
|
158
|
+
raise ValueError("anchor selector cannot mix id with kind/locator")
|
|
159
|
+
return self
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class AddGroundingAction(ConceptLifecycleActionFields):
|
|
163
|
+
"""Create an evidence-backed concept grounding."""
|
|
164
|
+
|
|
165
|
+
type: Literal["add_grounding"]
|
|
166
|
+
concept: str = Field(min_length=1)
|
|
167
|
+
role: ConceptGroundingRoleValue
|
|
168
|
+
anchor: AnchorSelector
|
|
169
|
+
evidence: list[ConceptEvidencePayload] = Field(min_length=1)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class LinkMemoryAction(ConceptLifecycleActionFields):
|
|
173
|
+
"""Create an evidence-backed concept-memory link."""
|
|
174
|
+
|
|
175
|
+
type: Literal["link_memory"]
|
|
176
|
+
concept: str = Field(min_length=1)
|
|
177
|
+
role: ConceptMemoryLinkRoleValue
|
|
178
|
+
memory_id: str = Field(min_length=1)
|
|
179
|
+
evidence: list[ConceptEvidencePayload] = Field(min_length=1)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
ConceptAction = Annotated[
|
|
183
|
+
UpsertConceptAction | AddRelationAction | AddClaimAction | UpsertAnchorAction | AddGroundingAction | LinkMemoryAction,
|
|
184
|
+
Field(discriminator="type"),
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class ConceptCommandRequest(StrictBaseModel):
|
|
189
|
+
"""Canonical concept endpoint request."""
|
|
190
|
+
|
|
191
|
+
schema_version: Literal["concept.v1"]
|
|
192
|
+
mode: Literal["apply", "show"]
|
|
193
|
+
repo_id: str
|
|
194
|
+
actions: list[ConceptAction] | None = None
|
|
195
|
+
concept: str | None = None
|
|
196
|
+
include: list[ConceptShowIncludeValue] = Field(default_factory=list)
|
|
197
|
+
|
|
198
|
+
@model_validator(mode="after")
|
|
199
|
+
def _validate_mode_fields(self) -> "ConceptCommandRequest":
|
|
200
|
+
"""Enforce mode-specific request fields."""
|
|
201
|
+
|
|
202
|
+
if self.mode == "apply":
|
|
203
|
+
if not self.actions:
|
|
204
|
+
raise ValueError("mode=apply requires actions")
|
|
205
|
+
if self.concept is not None:
|
|
206
|
+
raise ValueError("mode=apply does not accept concept")
|
|
207
|
+
if self.mode == "show":
|
|
208
|
+
if not self.concept:
|
|
209
|
+
raise ValueError("mode=show requires concept")
|
|
210
|
+
if self.actions is not None:
|
|
211
|
+
raise ValueError("mode=show does not accept actions")
|
|
212
|
+
return self
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from typing import Annotated, Literal
|
|
4
4
|
|
|
5
|
-
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
MemoryKindValue = Literal["problem", "solution", "failed_tactic", "fact", "preference", "change", "frontier"]
|
|
9
9
|
AssociationRelationValue = Literal["depends_on", "associated_with", "matures_into"]
|
|
10
|
+
ConceptReadFacetValue = Literal["claims", "relations", "groundings", "memory_links", "evidence"]
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class StrictBaseModel(BaseModel):
|
|
@@ -15,6 +16,43 @@ class StrictBaseModel(BaseModel):
|
|
|
15
16
|
model_config = ConfigDict(extra="forbid")
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
class ReadConceptsExpandRequest(StrictBaseModel):
|
|
20
|
+
"""This model defines concept-context read expansion controls."""
|
|
21
|
+
|
|
22
|
+
mode: Literal["auto", "none", "explicit"] = "auto"
|
|
23
|
+
refs: list[str] = Field(default_factory=list, max_length=5)
|
|
24
|
+
facets: list[ConceptReadFacetValue] = Field(default_factory=list, max_length=5)
|
|
25
|
+
max_auto: int = Field(default=2, ge=1, le=5)
|
|
26
|
+
|
|
27
|
+
@field_validator("refs")
|
|
28
|
+
@classmethod
|
|
29
|
+
def _validate_refs_unique(cls, value: list[str]) -> list[str]:
|
|
30
|
+
"""This validator enforces unique concept refs."""
|
|
31
|
+
|
|
32
|
+
if any(not ref.strip() for ref in value):
|
|
33
|
+
raise ValueError("concept refs must be non-empty")
|
|
34
|
+
if len(value) != len(set(value)):
|
|
35
|
+
raise ValueError("concept refs must be unique")
|
|
36
|
+
return value
|
|
37
|
+
|
|
38
|
+
@field_validator("facets")
|
|
39
|
+
@classmethod
|
|
40
|
+
def _validate_facets_unique(cls, value: list[ConceptReadFacetValue]) -> list[ConceptReadFacetValue]:
|
|
41
|
+
"""This validator enforces unique concept facets."""
|
|
42
|
+
|
|
43
|
+
if len(value) != len(set(value)):
|
|
44
|
+
raise ValueError("concept facets must be unique")
|
|
45
|
+
return value
|
|
46
|
+
|
|
47
|
+
@model_validator(mode="after")
|
|
48
|
+
def _validate_explicit_refs(self) -> "ReadConceptsExpandRequest":
|
|
49
|
+
"""Require explicit concept refs when explicit mode is requested."""
|
|
50
|
+
|
|
51
|
+
if self.mode == "explicit" and not self.refs:
|
|
52
|
+
raise ValueError("expand.concepts.mode=explicit requires refs")
|
|
53
|
+
return self
|
|
54
|
+
|
|
55
|
+
|
|
18
56
|
class ReadExpandRequest(StrictBaseModel):
|
|
19
57
|
"""This model defines expansion knobs for read requests."""
|
|
20
58
|
|
|
@@ -24,6 +62,7 @@ class ReadExpandRequest(StrictBaseModel):
|
|
|
24
62
|
include_association_links: bool | None = None
|
|
25
63
|
max_association_depth: int | None = Field(default=None, ge=1, le=4)
|
|
26
64
|
min_association_strength: float | None = Field(default=None, ge=0.0, le=1.0)
|
|
65
|
+
concepts: ReadConceptsExpandRequest = Field(default_factory=ReadConceptsExpandRequest)
|
|
27
66
|
|
|
28
67
|
|
|
29
68
|
class MemoryReadRequest(StrictBaseModel):
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"""Core entities and enums for the typed concept-context graph."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ConceptKind(str, Enum):
|
|
12
|
+
"""Allowed high-level concept kinds."""
|
|
13
|
+
|
|
14
|
+
DOMAIN = "domain"
|
|
15
|
+
CAPABILITY = "capability"
|
|
16
|
+
PROCESS = "process"
|
|
17
|
+
ENTITY = "entity"
|
|
18
|
+
RULE = "rule"
|
|
19
|
+
COMPONENT = "component"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ConceptStatus(str, Enum):
|
|
23
|
+
"""Lifecycle state for concept containers."""
|
|
24
|
+
|
|
25
|
+
ACTIVE = "active"
|
|
26
|
+
DEPRECATED = "deprecated"
|
|
27
|
+
ARCHIVED = "archived"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ConceptLifecycleStatus(str, Enum):
|
|
31
|
+
"""Lifecycle state for truth-bearing concept records."""
|
|
32
|
+
|
|
33
|
+
ACTIVE = "active"
|
|
34
|
+
MAYBE_STALE = "maybe_stale"
|
|
35
|
+
STALE = "stale"
|
|
36
|
+
SUPERSEDED = "superseded"
|
|
37
|
+
WRONG = "wrong"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ConceptRelationPredicate(str, Enum):
|
|
41
|
+
"""Allowed concept-to-concept predicates."""
|
|
42
|
+
|
|
43
|
+
CONTAINS = "contains"
|
|
44
|
+
INVOLVES = "involves"
|
|
45
|
+
PRECEDES = "precedes"
|
|
46
|
+
CONSTRAINS = "constrains"
|
|
47
|
+
DEPENDS_ON = "depends_on"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ConceptClaimType(str, Enum):
|
|
51
|
+
"""Allowed concept claim types."""
|
|
52
|
+
|
|
53
|
+
DEFINITION = "definition"
|
|
54
|
+
BEHAVIOR = "behavior"
|
|
55
|
+
INVARIANT = "invariant"
|
|
56
|
+
FAILURE_MODE = "failure_mode"
|
|
57
|
+
USAGE_NOTE = "usage_note"
|
|
58
|
+
OPEN_QUESTION = "open_question"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class AnchorKind(str, Enum):
|
|
62
|
+
"""Allowed real-world locator kinds."""
|
|
63
|
+
|
|
64
|
+
FILE = "file"
|
|
65
|
+
SYMBOL = "symbol"
|
|
66
|
+
LINE_RANGE = "line_range"
|
|
67
|
+
API_ROUTE = "api_route"
|
|
68
|
+
DB_TABLE = "db_table"
|
|
69
|
+
SCHEMA = "schema"
|
|
70
|
+
CONFIG_KEY = "config_key"
|
|
71
|
+
TEST = "test"
|
|
72
|
+
METRIC = "metric"
|
|
73
|
+
LOG = "log"
|
|
74
|
+
DOC = "doc"
|
|
75
|
+
COMMIT = "commit"
|
|
76
|
+
MEMORY = "memory"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class AnchorStatus(str, Enum):
|
|
80
|
+
"""Lifecycle state for real-world locators."""
|
|
81
|
+
|
|
82
|
+
ACTIVE = "active"
|
|
83
|
+
MAYBE_STALE = "maybe_stale"
|
|
84
|
+
STALE = "stale"
|
|
85
|
+
DEPRECATED = "deprecated"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ConceptGroundingRole(str, Enum):
|
|
89
|
+
"""Allowed concept-to-anchor grounding roles."""
|
|
90
|
+
|
|
91
|
+
IMPLEMENTATION = "implementation"
|
|
92
|
+
ENTRYPOINT = "entrypoint"
|
|
93
|
+
STORAGE = "storage"
|
|
94
|
+
CONFIGURATION = "configuration"
|
|
95
|
+
TEST = "test"
|
|
96
|
+
OBSERVABILITY = "observability"
|
|
97
|
+
DOCUMENTATION = "documentation"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class ConceptMemoryLinkRole(str, Enum):
|
|
101
|
+
"""Allowed concept-to-memory link roles."""
|
|
102
|
+
|
|
103
|
+
EXAMPLE_OF = "example_of"
|
|
104
|
+
SOLUTION_FOR = "solution_for"
|
|
105
|
+
FAILED_TACTIC_FOR = "failed_tactic_for"
|
|
106
|
+
CHANGED = "changed"
|
|
107
|
+
VALIDATED = "validated"
|
|
108
|
+
CONTRADICTED = "contradicted"
|
|
109
|
+
WARNED_ABOUT = "warned_about"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ConceptEvidenceTargetType(str, Enum):
|
|
113
|
+
"""Truth-bearing concept record types that evidence may target."""
|
|
114
|
+
|
|
115
|
+
RELATION = "relation"
|
|
116
|
+
CLAIM = "claim"
|
|
117
|
+
GROUNDING = "grounding"
|
|
118
|
+
MEMORY_LINK = "memory_link"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class ConceptEvidenceKind(str, Enum):
|
|
122
|
+
"""Allowed evidence source kinds for concept records."""
|
|
123
|
+
|
|
124
|
+
ANCHOR = "anchor"
|
|
125
|
+
MEMORY = "memory"
|
|
126
|
+
COMMIT = "commit"
|
|
127
|
+
TRANSCRIPT = "transcript"
|
|
128
|
+
TEST = "test"
|
|
129
|
+
MANUAL = "manual"
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ConceptSourceKind(str, Enum):
|
|
133
|
+
"""Allowed source refs on concept lifecycle records."""
|
|
134
|
+
|
|
135
|
+
COMMIT = "commit"
|
|
136
|
+
FILE_HASH = "file_hash"
|
|
137
|
+
SYMBOL_HASH = "symbol_hash"
|
|
138
|
+
MEMORY = "memory"
|
|
139
|
+
TRANSCRIPT_EVENT = "transcript_event"
|
|
140
|
+
MANUAL = "manual"
|
|
141
|
+
DOC = "doc"
|
|
142
|
+
RUNTIME_TRACE = "runtime_trace"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class ConceptCreatedBy(str, Enum):
|
|
146
|
+
"""Allowed authorship channels for concept records."""
|
|
147
|
+
|
|
148
|
+
WORKER = "worker"
|
|
149
|
+
LIBRARIAN = "librarian"
|
|
150
|
+
MANUAL = "manual"
|
|
151
|
+
IMPORT = "import"
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class GraphPatchStatus(str, Enum):
|
|
155
|
+
"""Allowed graph patch lifecycle states."""
|
|
156
|
+
|
|
157
|
+
PENDING = "pending"
|
|
158
|
+
APPLIED = "applied"
|
|
159
|
+
REJECTED = "rejected"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@dataclass(frozen=True, kw_only=True)
|
|
163
|
+
class Concept:
|
|
164
|
+
"""One durable concept container."""
|
|
165
|
+
|
|
166
|
+
id: str
|
|
167
|
+
repo_id: str
|
|
168
|
+
slug: str
|
|
169
|
+
name: str
|
|
170
|
+
kind: ConceptKind
|
|
171
|
+
status: ConceptStatus = ConceptStatus.ACTIVE
|
|
172
|
+
scope_note: str | None = None
|
|
173
|
+
created_at: datetime | None = None
|
|
174
|
+
updated_at: datetime | None = None
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@dataclass(frozen=True, kw_only=True)
|
|
178
|
+
class ConceptAlias:
|
|
179
|
+
"""One alternate label for a concept."""
|
|
180
|
+
|
|
181
|
+
concept_id: str
|
|
182
|
+
repo_id: str
|
|
183
|
+
alias: str
|
|
184
|
+
normalized_alias: str
|
|
185
|
+
created_at: datetime | None = None
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@dataclass(frozen=True, kw_only=True)
|
|
189
|
+
class ConceptLifecycle:
|
|
190
|
+
"""Shared lifecycle fields for truth-bearing concept records."""
|
|
191
|
+
|
|
192
|
+
status: ConceptLifecycleStatus = ConceptLifecycleStatus.ACTIVE
|
|
193
|
+
confidence: float = 0.5
|
|
194
|
+
observed_at: datetime | None = None
|
|
195
|
+
validated_at: datetime | None = None
|
|
196
|
+
source_kind: ConceptSourceKind | None = None
|
|
197
|
+
source_ref: str | None = None
|
|
198
|
+
superseded_by_id: str | None = None
|
|
199
|
+
created_by: ConceptCreatedBy = ConceptCreatedBy.MANUAL
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@dataclass(frozen=True, kw_only=True)
|
|
203
|
+
class ConceptRelation:
|
|
204
|
+
"""One typed concept-to-concept relation."""
|
|
205
|
+
|
|
206
|
+
id: str
|
|
207
|
+
repo_id: str
|
|
208
|
+
subject_concept_id: str
|
|
209
|
+
predicate: ConceptRelationPredicate
|
|
210
|
+
object_concept_id: str
|
|
211
|
+
lifecycle: ConceptLifecycle = field(default_factory=ConceptLifecycle)
|
|
212
|
+
created_at: datetime | None = None
|
|
213
|
+
updated_at: datetime | None = None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@dataclass(frozen=True, kw_only=True)
|
|
217
|
+
class ConceptClaim:
|
|
218
|
+
"""One typed statement Shellbrain believes about a concept."""
|
|
219
|
+
|
|
220
|
+
id: str
|
|
221
|
+
repo_id: str
|
|
222
|
+
concept_id: str
|
|
223
|
+
claim_type: ConceptClaimType
|
|
224
|
+
text: str
|
|
225
|
+
normalized_text: str
|
|
226
|
+
lifecycle: ConceptLifecycle = field(default_factory=ConceptLifecycle)
|
|
227
|
+
created_at: datetime | None = None
|
|
228
|
+
updated_at: datetime | None = None
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@dataclass(frozen=True, kw_only=True)
|
|
232
|
+
class Anchor:
|
|
233
|
+
"""One real-world locator that grounds a concept."""
|
|
234
|
+
|
|
235
|
+
id: str
|
|
236
|
+
repo_id: str
|
|
237
|
+
kind: AnchorKind
|
|
238
|
+
locator_json: dict[str, Any]
|
|
239
|
+
canonical_locator_hash: str
|
|
240
|
+
status: AnchorStatus = AnchorStatus.ACTIVE
|
|
241
|
+
created_at: datetime | None = None
|
|
242
|
+
updated_at: datetime | None = None
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@dataclass(frozen=True, kw_only=True)
|
|
246
|
+
class ConceptGrounding:
|
|
247
|
+
"""One typed link from concept space to a real-world anchor."""
|
|
248
|
+
|
|
249
|
+
id: str
|
|
250
|
+
repo_id: str
|
|
251
|
+
concept_id: str
|
|
252
|
+
role: ConceptGroundingRole
|
|
253
|
+
anchor_id: str
|
|
254
|
+
lifecycle: ConceptLifecycle = field(default_factory=ConceptLifecycle)
|
|
255
|
+
created_at: datetime | None = None
|
|
256
|
+
updated_at: datetime | None = None
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@dataclass(frozen=True, kw_only=True)
|
|
260
|
+
class ConceptMemoryLink:
|
|
261
|
+
"""One typed link from an existing Shellbrain memory to a concept."""
|
|
262
|
+
|
|
263
|
+
id: str
|
|
264
|
+
repo_id: str
|
|
265
|
+
concept_id: str
|
|
266
|
+
role: ConceptMemoryLinkRole
|
|
267
|
+
memory_id: str
|
|
268
|
+
lifecycle: ConceptLifecycle = field(default_factory=ConceptLifecycle)
|
|
269
|
+
created_at: datetime | None = None
|
|
270
|
+
updated_at: datetime | None = None
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@dataclass(frozen=True, kw_only=True)
|
|
274
|
+
class ConceptEvidence:
|
|
275
|
+
"""One evidence pointer attached to a truth-bearing concept record."""
|
|
276
|
+
|
|
277
|
+
id: str
|
|
278
|
+
repo_id: str
|
|
279
|
+
target_type: ConceptEvidenceTargetType
|
|
280
|
+
target_id: str
|
|
281
|
+
evidence_kind: ConceptEvidenceKind
|
|
282
|
+
anchor_id: str | None = None
|
|
283
|
+
memory_id: str | None = None
|
|
284
|
+
commit_ref: str | None = None
|
|
285
|
+
transcript_ref: str | None = None
|
|
286
|
+
note: str | None = None
|
|
287
|
+
created_at: datetime | None = None
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@dataclass(frozen=True, kw_only=True)
|
|
291
|
+
class GraphPatch:
|
|
292
|
+
"""Minimal reserved future graph-patch proposal record."""
|
|
293
|
+
|
|
294
|
+
id: str
|
|
295
|
+
repo_id: str
|
|
296
|
+
schema_version: str
|
|
297
|
+
status: GraphPatchStatus
|
|
298
|
+
proposed_by: ConceptCreatedBy
|
|
299
|
+
operations_json: list[dict[str, Any]]
|
|
300
|
+
evidence_summary: str | None = None
|
|
301
|
+
created_at: datetime | None = None
|
|
302
|
+
applied_at: datetime | None = None
|