theurian 0.1.0.dev7__tar.gz → 0.1.0.dev8__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.
Files changed (251) hide show
  1. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/.gitignore +11 -11
  2. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/CHANGELOG.md +160 -0
  3. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/PKG-INFO +2 -1
  4. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/pyproject.toml +6 -1
  5. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/__init__.py +1 -1
  6. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/proposal_service.py +538 -42
  7. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/commands.py +27 -6
  8. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/main.py +5 -1
  9. theurian-0.1.0.dev8/src/theurian/cli/output.py +61 -0
  10. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/propose_commands.py +33 -10
  11. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/errors.py +220 -8
  12. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/proposal.py +36 -6
  13. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/filesystem/migration_loader.py +231 -24
  14. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/security/paths.py +8 -4
  15. theurian-0.1.0.dev8/tests/command_population.py +526 -0
  16. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_cli_commands.py +217 -0
  17. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_proposal_service.py +708 -13
  18. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_propose_cli.py +205 -0
  19. theurian-0.1.0.dev8/tests/unit/test_command_population.py +763 -0
  20. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_documented_commands.py +49 -49
  21. theurian-0.1.0.dev8/tests/unit/test_dogfood_corpus_governance.py +1464 -0
  22. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_migration_loader_errors.py +716 -9
  23. theurian-0.1.0.dev8/tests/unit/test_path_security.py +383 -0
  24. theurian-0.1.0.dev7/tests/command_population.py +0 -210
  25. theurian-0.1.0.dev7/tests/unit/test_path_security.py +0 -198
  26. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/LICENSE +0 -0
  27. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/README.md +0 -0
  28. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/hatch_build.py +0 -0
  29. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/__init__.py +0 -0
  30. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/forest_builder.py +0 -0
  31. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/index_builder.py +0 -0
  32. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/ingestion_service.py +0 -0
  33. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/migration_alias_guards.py +0 -0
  34. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/migration_body_guards.py +0 -0
  35. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/migration_engine.py +0 -0
  36. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/project_service.py +0 -0
  37. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/retrieval_service.py +0 -0
  38. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/setup_context.py +0 -0
  39. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/setup_service.py +0 -0
  40. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/setup_steps.py +0 -0
  41. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/setup_withholding.py +0 -0
  42. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/visibility.py +0 -0
  43. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/application/withdrawal_purge.py +0 -0
  44. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/__init__.py +0 -0
  45. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/auth_commands.py +0 -0
  46. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/context.py +0 -0
  47. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/index_commands.py +0 -0
  48. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/cli/setup_commands.py +0 -0
  49. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/daemon/__init__.py +0 -0
  50. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/daemon/instance.py +0 -0
  51. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/daemon/runner.py +0 -0
  52. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/daemon/server.py +0 -0
  53. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/__init__.py +0 -0
  54. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/chunking.py +0 -0
  55. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/compatibility.py +0 -0
  56. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/context.py +0 -0
  57. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/enums.py +0 -0
  58. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/extras.py +0 -0
  59. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/identifiers.py +0 -0
  60. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ingestion.py +0 -0
  61. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/knowledge.py +0 -0
  62. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/migration.py +0 -0
  63. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/__init__.py +0 -0
  64. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/authorization.py +0 -0
  65. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/canonical_store.py +0 -0
  66. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/daemon_manager.py +0 -0
  67. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/determinism.py +0 -0
  68. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/embedding.py +0 -0
  69. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/index_store.py +0 -0
  70. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/mcp_client_config.py +0 -0
  71. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/object_store.py +0 -0
  72. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/reranking.py +0 -0
  73. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/review_provider.py +0 -0
  74. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/secret_store.py +0 -0
  75. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/source_parser.py +0 -0
  76. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/specification_provider.py +0 -0
  77. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/summarization.py +0 -0
  78. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ports/vector_store.py +0 -0
  79. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/project.py +0 -0
  80. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/ranking.py +0 -0
  81. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/raptor.py +0 -0
  82. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/retrieval.py +0 -0
  83. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/review.py +0 -0
  84. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/setup.py +0 -0
  85. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/specification.py +0 -0
  86. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/state.py +0 -0
  87. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/domain/values.py +0 -0
  88. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/indexing/__init__.py +0 -0
  89. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/__init__.py +0 -0
  90. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/claude/__init__.py +0 -0
  91. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/claude/mcp_config.py +0 -0
  92. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/determinism.py +0 -0
  93. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/embedding/__init__.py +0 -0
  94. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/embedding/hashing.py +0 -0
  95. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/filesystem/__init__.py +0 -0
  96. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/filesystem/parsers/markdown.py +0 -0
  97. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/filesystem/parsers/openapi.py +0 -0
  98. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/filesystem/parsers/registry.py +0 -0
  99. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/filesystem/parsers/structured.py +0 -0
  100. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/git/__init__.py +0 -0
  101. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/github/__init__.py +0 -0
  102. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/raptor/__init__.py +0 -0
  103. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/raptor/extractive.py +0 -0
  104. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/secrets/__init__.py +0 -0
  105. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/secrets/file_store.py +0 -0
  106. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/services/__init__.py +0 -0
  107. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/services/launchagent.py +0 -0
  108. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/services/runner.py +0 -0
  109. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/services/systemd_user.py +0 -0
  110. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/__init__.py +0 -0
  111. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/connection.py +0 -0
  112. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/index_forest.py +0 -0
  113. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/index_purge.py +0 -0
  114. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/index_query.py +0 -0
  115. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/index_scan.py +0 -0
  116. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/index_schema.py +0 -0
  117. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/index_store.py +0 -0
  118. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/schema.py +0 -0
  119. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/sqlite/store.py +0 -0
  120. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/infrastructure/vector/__init__.py +0 -0
  121. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/ingestion/__init__.py +0 -0
  122. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/mcp/__init__.py +0 -0
  123. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/mcp/results.py +0 -0
  124. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/mcp/search.py +0 -0
  125. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/mcp/tools.py +0 -0
  126. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/migrations/__init__.py +0 -0
  127. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/normalization/__init__.py +0 -0
  128. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/normalization/projection.py +0 -0
  129. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/observability/__init__.py +0 -0
  130. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/retrieval/__init__.py +0 -0
  131. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/review/__init__.py +0 -0
  132. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/security/__init__.py +0 -0
  133. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/security/env_file.py +0 -0
  134. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/security/tokens.py +0 -0
  135. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/security/yaml_loading.py +0 -0
  136. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/specification/__init__.py +0 -0
  137. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/src/theurian/traceability/__init__.py +0 -0
  138. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/command_extraction.py +0 -0
  139. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/conftest.py +0 -0
  140. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/fakes/__init__.py +0 -0
  141. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/fakes/clock.py +0 -0
  142. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/fakes/ids.py +0 -0
  143. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/fakes/pages.py +0 -0
  144. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/fakes/setup.py +0 -0
  145. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/fakes/store.py +0 -0
  146. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_absence_proof.py +0 -0
  147. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_alias_item_id_collision.py +0 -0
  148. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_auth_rotate.py +0 -0
  149. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_bare_install.py +0 -0
  150. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_canonical_store.py +0 -0
  151. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_canonical_store_corruption.py +0 -0
  152. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_claude_mcp_config.py +0 -0
  153. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_cli_help_without_rich.py +0 -0
  154. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_daemon.py +0 -0
  155. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_builder.py +0 -0
  156. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_builder_scale.py +0 -0
  157. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_node_scope.py +0 -0
  158. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_purge_equality.py +0 -0
  159. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_purge_recompute.py +0 -0
  160. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_retrieval.py +0 -0
  161. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_forest_store_retrieval.py +0 -0
  162. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_gc_during_a_search.py +0 -0
  163. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_fallback.py +0 -0
  164. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_gc_cli.py +0 -0
  165. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_purge.py +0 -0
  166. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_purge_differential.py +0 -0
  167. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_purge_nodes.py +0 -0
  168. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_scan_fold.py +0 -0
  169. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_schema_v4.py +0 -0
  170. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_index_store.py +0 -0
  171. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_ingestion.py +0 -0
  172. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_init_gitignore_block.py +0 -0
  173. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_mcp_tools.py +0 -0
  174. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_project_registry.py +0 -0
  175. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_retrieval_service.py +0 -0
  176. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_revision_id_reuse.py +0 -0
  177. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_scan_exhaustion.py +0 -0
  178. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_service_adapters.py +0 -0
  179. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_session_start_hook.py +0 -0
  180. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_cli.py +0 -0
  181. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_env_file.py +0 -0
  182. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_journal.py +0 -0
  183. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_partial_failure.py +0 -0
  184. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_probe_assertions.py +0 -0
  185. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_report_withholding.py +0 -0
  186. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_setup_service.py +0 -0
  187. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_short_query_retrieval.py +0 -0
  188. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_state_provenance.py +0 -0
  189. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_unreadable_registry_surface.py +0 -0
  190. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_wire_contract.py +0 -0
  191. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_withdrawal_purge.py +0 -0
  192. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/integration/test_writer_contract.py +0 -0
  193. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_artifact_integrity_claim.py +0 -0
  194. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_candidate_cut.py +0 -0
  195. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_candidate_depth.py +0 -0
  196. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_chunking.py +0 -0
  197. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_cli_help_rendering.py +0 -0
  198. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_command_extraction.py +0 -0
  199. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_compatibility.py +0 -0
  200. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_config_key_call_sites.py +0 -0
  201. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_daemon_extra.py +0 -0
  202. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_domain_invariants.py +0 -0
  203. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_env_file_merge.py +0 -0
  204. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_examples.py +0 -0
  205. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_extractive_summarizer.py +0 -0
  206. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_forest_derivation.py +0 -0
  207. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_forest_fanout.py +0 -0
  208. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_gate_call_sites.py +0 -0
  209. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_hashing_embedding.py +0 -0
  210. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_ingest_manifest_path.py +0 -0
  211. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_install_claims.py +0 -0
  212. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_layering.py +0 -0
  213. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_migration_alias_guards.py +0 -0
  214. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_migration_engine.py +0 -0
  215. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_migration_loader_identity.py +0 -0
  216. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_network_call_sites.py +0 -0
  217. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_parsers.py +0 -0
  218. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_plugin_boundary.py +0 -0
  219. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_ports.py +0 -0
  220. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_project_and_traceability.py +0 -0
  221. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_project_registry_errors.py +0 -0
  222. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_projection.py +0 -0
  223. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_proposal.py +0 -0
  224. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_ranking.py +0 -0
  225. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_raptor_scope.py +0 -0
  226. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_ref_recording.py +0 -0
  227. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_resolve_context_call_sites.py +0 -0
  228. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_result_gate_session.py +0 -0
  229. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_result_payload.py +0 -0
  230. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_retrieval_depth.py +0 -0
  231. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_schemas.py +0 -0
  232. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_scope_isolation.py +0 -0
  233. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_secret_detector.py +0 -0
  234. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_setup_changed_paths.py +0 -0
  235. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_setup_claims.py +0 -0
  236. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_setup_domain.py +0 -0
  237. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_state_hash.py +0 -0
  238. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_test_fixtures.py +0 -0
  239. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_tokens.py +0 -0
  240. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/tests/unit/test_yaml_loading.py +0 -0
  241. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/README.md +0 -0
  242. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/cli/version.schema.json +0 -0
  243. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/config/project-config.schema.json +0 -0
  244. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/knowledge/retrieval-result.schema.json +0 -0
  245. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/mcp/knowledge-search-response.schema.json +0 -0
  246. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/mcp/knowledge-status-response.schema.json +0 -0
  247. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/mcp/project-list-response.schema.json +0 -0
  248. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/mcp/retrieval-metadata.schema.json +0 -0
  249. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/mcp/tool-context.schema.json +0 -0
  250. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/migrations/migration.schema.json +0 -0
  251. {theurian-0.1.0.dev7 → theurian-0.1.0.dev8}/theurian/schemas/protocol/compatibility.schema.json +0 -0
@@ -19,17 +19,6 @@ dist/
19
19
  coverage.xml
20
20
  htmlcov/
21
21
 
22
- # --- Theurian derived artifacts -------------------------------------------
23
- # Canonical state is rebuilt from Git-tracked migrations and content.
24
- # Never commit any of these. See docs/adr/0004-sqlite-is-a-derived-artifact.md
25
- .theurian/state/
26
- .theurian/cache/
27
- .theurian/runtime/
28
- .theurian/generated/
29
- *.sqlite
30
- *.sqlite-wal
31
- *.sqlite-shm
32
-
33
22
  # --- Documentation site (derived) ---
34
23
  # `mkdocs build` writes site/. The Pages workflow copies the logo into
35
24
  # docs/assets/ before building, so anyone replicating that build locally
@@ -58,3 +47,14 @@ htmlcov/
58
47
  .env.*
59
48
  !.env.example
60
49
  *.token
50
+
51
+ # >>> theurian >>>
52
+ # Derived artifacts. Rebuilt from Git-tracked migrations (ADR-0004).
53
+ .theurian/state/
54
+ .theurian/cache/
55
+ .theurian/runtime/
56
+ .theurian/generated/
57
+ *.sqlite
58
+ *.sqlite-wal
59
+ *.sqlite-shm
60
+ # <<< theurian <<<
@@ -12,6 +12,166 @@ Pre-1.0, a MINOR bump may change the protocol. Post-1.0, only a MAJOR may.
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [0.1.0.dev8] - 2026-08-20
16
+
17
+ ### Added
18
+
19
+ - **`evidence.json` now records the `migrationId` and `itemId` its proposal
20
+ drafted** ([#253](https://github.com/theurian/theurian/issues/253)). These are
21
+ the two fields of that file Core reads back: together they let `propose accept`
22
+ ask whether a migration with that id, operating on that item, is in
23
+ `.theurian/migrations/`. Both are a contributor's claim, not authority —
24
+ `evidence.json` is committed and untrusted (ADR-0013 point 7) — so `itemId` is
25
+ the cross-check that stops a forged `migrationId` (one pointing at another
26
+ proposal's landed migration) from reading as accepted. Optional on read: the 26
27
+ proposals committed in this repository predate both fields and are diagnosed by
28
+ best-effort inference, which their message says.
29
+
30
+ ### Fixed
31
+
32
+ - **The installed migration schema resolved `$ref`s over the network, and its
33
+ resolution failures escaped as raw tracebacks**
34
+ ([#235](https://github.com/theurian/theurian/issues/235)). The migration
35
+ schema was validated with `jsonschema`'s default registry, whose retrieve
36
+ callable fetches an external `$ref` over the network
37
+ (`urllib.request.urlopen`) at validate time — and reads a `file://` ref off
38
+ disk the same way. An SSRF-shaped read gated only on the installed schema
39
+ being corrupted or replaced (an operator-side precondition; `schema_root()`
40
+ never reads user-project paths), and covered by no existing claim:
41
+ `parsers/openapi.py`'s "external `$ref` targets are recorded, never fetched"
42
+ governs *ingested* documents, not the schema this build ships. Every
43
+ validator is now built with `referencing`'s `EMPTY_REGISTRY` — no retrieve
44
+ callable — so an external `$ref` fails closed; internal `#/$defs/…` refs
45
+ still resolve from the schema's own root resource, so the bundled schema
46
+ validates unchanged. Separately, the resulting resolution failures — an
47
+ unresolvable `$ref`/`$dynamicRef` raises `referencing.exceptions.Unresolvable`
48
+ and a self-recursive or empty `$ref` raises `RecursionError`, neither a
49
+ `ValidationError` — used to slip past every `except ValidationError` seam and
50
+ reach `resolve_context` as a raw traceback under `--json`. Both are now
51
+ translated to `SchemaUnreadableError`, the type every other
52
+ installed-schema-corruption failure already carries, at both validate seams
53
+ (`migrate validate` / `propose`, and any command that loads migrations from
54
+ disk).
55
+ - **A path-containment refusal told the user to go somewhere they already were,
56
+ and could instruct them to delete their own work**
57
+ ([#233](https://github.com/theurian/theurian/issues/233)). With
58
+ `.theurian/migrations` — or one `*.yaml` file inside it — a symlink pointing
59
+ outside the project, `theurian migrate validate --json` printed
60
+ `{"error": "Path escapes the permitted root /<absolute>/<project>", "remedy":
61
+ "Run this inside an initialised Theurian project."}` at exit 1. The refusal
62
+ itself was correct and is unchanged; what it said about itself was not.
63
+ `PathEscapeError` set no `remedy` of its own, so the CLI's generic fallback
64
+ won — the "exception that does not describe itself" shape
65
+ [#205](https://github.com/theurian/theurian/issues/205) exists to end. It now
66
+ names, relative to the project root and with the `!r` quoting its siblings
67
+ use, *where* the problem is — and **no remedy names a file to delete.** That
68
+ is the substantive change: an escape happens through a symbolic link somewhere
69
+ on the entry's ancestor chain or its resolution chain, and which link it is
70
+ cannot be determined from the entry alone. Three successive attempts to
71
+ determine it anyway were each refuted by a deeper construction — the last by
72
+ `x.yaml → y.yaml → outside`, where following the remedy deleted two
73
+ Git-tracked files and ended at `valid: true` while the minimal cure was
74
+ repointing `y` alone. So the remedy now states only what `lstat` proves — that
75
+ the named entry is or is not itself a link — and then hands over the finite
76
+ checklist: this entry, the directories above it, the links it resolves
77
+ through. "Repoint that link, or remove that link" refers to whichever the
78
+ reader finds; Theurian never names it. Related: an outside-pointing
79
+ `.theurian` is reachable from a plain `git clone`
80
+ ([#237](https://github.com/theurian/theurian/issues/237)). The offending path
81
+ is still never echoed (SEC-7), and neither is the absolute project root.
82
+ - **A `contentFile` refusal no longer denies the commonest cure.** The
83
+ path-escape remedy for a `contentFile` used to say that removing the `..` was
84
+ "not the cure" — wrong for a plain over-traversal typo, which involves no
85
+ symlink at all and is fixed by exactly that edit, and in conflict with the
86
+ sibling `MigrationContentUnreadableError`, which tells the author to fix the
87
+ path. It now offers both candidates: correct the path, or find the link
88
+ something it traverses goes through.
89
+ - **Exit code:** a `PathEscapeError` raised while resolving a project now exits
90
+ `EXIT_STATE_ERROR` (4) rather than 1 for the commands routed through
91
+ `_require_project` — measured, all nine: `migrate validate`, `migrate status`,
92
+ `migrate apply`, `index build`, `index status`, `index gc`, `ingest`,
93
+ `propose` and `propose accept` — matching every sibling refusal on the same
94
+ load path (`MigrationsDirectoryUnreadableError`,
95
+ `MigrationFileUnreadableError`, `MigrationError`). A script keying on exit 1
96
+ for those must be updated. `init` and `project register` call
97
+ `resolve_context` directly and still exit 1; `project status` reports at exit
98
+ 0 as it always has. All three now carry the new remedy text.
99
+ - **A path refused only for nesting too deep no longer claims to have escaped**
100
+ ([#233](https://github.com/theurian/theurian/issues/233)). `resolve_within_root`
101
+ refuses a path past `MAX_PATH_DEPTH` whether or not it ever leaves the root,
102
+ and reported it as `Path escapes the permitted root` — false for a path
103
+ sitting entirely inside. It now raises `PathDepthExceededError` with its own
104
+ message and a remedy about flattening the nesting. The new type is a
105
+ `PathEscapeError` subclass, so every existing `except` and every exit-code
106
+ route catches it unchanged; only what the caller is told differs.
107
+ - **An interrupted `theurian propose` was diagnosed as an accepted one**
108
+ ([#253](https://github.com/theurian/theurian/issues/253)). `propose accept`
109
+ read the presence of `evidence.json` as "this proposal has already been
110
+ accepted", but `propose` writes the body, then the evidence, then the
111
+ migration — so a run killed before its last write left exactly that shape.
112
+ `accept` reported that the migration had been moved into
113
+ `.theurian/migrations/` and that no action was needed beyond opening a pull
114
+ request, while `.theurian/migrations/` held nothing and the drafted knowledge
115
+ existed nowhere. The remedy discarded the draft.
116
+
117
+ Acceptance is a **best-effort diagnosis over untrusted input, not a
118
+ tamper-proof fact**: the proposal directory is contributor-controlled, so the
119
+ recorded `migrationId` is a claim (cross-checked by `itemId` against the
120
+ migration it names), a `evidence.json` that is present but unreadable is
121
+ answered as *indeterminate* rather than collapsed into "no record", and every
122
+ fallible branch points the reader at `.theurian/migrations/` first — no branch
123
+ emits an unconditional "no action is needed" or "draft it again", so none can
124
+ tell the author to discard work that may exist or duplicate a change that
125
+ already landed. Whether a migration is in place under the recorded id is read
126
+ from the same approved `MigrationSet` `migrate validate`/`apply` read — keyed by
127
+ the migration's inner id, not by a filename match — so `propose accept` cannot
128
+ disagree with the loader about what has landed, whatever a migration file was
129
+ renamed to or whether it is a symlink. The three states are kept distinct by
130
+ their exit codes: a migration in place under the recorded id — whether or not
131
+ the item cross-checks — exits 4 ("read before acting"), and only a recorded id
132
+ the loaded set holds *no* migration for exits 1 ("nothing landed, re-draft"), so
133
+ following exit 1 can never mint a duplicate of a change on disk. Absent
134
+ `evidence.json` (a legacy proposal, or
135
+ one interrupted before its evidence write) falls to inference over the
136
+ directory, which reads only the body shape the generator produces, so a
137
+ reviewer's notes or a `Thumbs.db` left beside an accepted proposal no longer
138
+ flips the verdict.
139
+
140
+ - **A committed proposal could forge `theurian propose accept`'s own output**
141
+ ([#253](https://github.com/theurian/theurian/issues/253)). A proposal directory
142
+ arrives through a contributor's pull request, and a file name or a migration's
143
+ `contentFile` carrying `ESC [ 2 K` and a carriage return erases the line the
144
+ terminal has drawn and prints its own in place of it — reproduced printing this
145
+ command's own output under its own name, on both the refusal path and the
146
+ exit-0 **success** payload (`bodyFiles`, `migrationFile`). The CLI now escapes
147
+ every terminal-control character — the whole C0 block, `DEL` and C1 — at one
148
+ shared sink that every text-mode emitter routes each value and key through, so
149
+ no value any command prints, from any source, reaches a terminal with a raw
150
+ control byte. A value's own newline is escaped too (the output's structural
151
+ newlines are the emitters' own), while printable Unicode (a Japanese title) is
152
+ kept. The `--json` output was never affected.
153
+
154
+ ### Changed
155
+
156
+ - **BREAKING — re-accepting an already-accepted proposal now exits 4, not 1**
157
+ ([#254](https://github.com/theurian/theurian/issues/254)). The published exit
158
+ code table documented 4 for "that migration is already in place", while the
159
+ natural route to that state — running `theurian propose accept` twice — exited
160
+ 1 alongside "no such proposal", an interrupted draft, and a refused
161
+ `contentFile`. Exit 4 keeps its meaning and gains this case: *the knowledge
162
+ state refuses this move, so read it before acting*. It is not "already done" —
163
+ an approved migration set that cannot be read also exits 4, with the proposal
164
+ still waiting — and the published table now says so rather than promising that
165
+ 1 always means nothing landed. Scripts that treat any non-zero exit as failure
166
+ are unaffected; one that special-cased 1 for "already accepted" must read 4.
167
+
168
+ Breaking by the compatibility table in
169
+ [`docs/protocol/plugin-core-compatibility.md`](../../docs/protocol/plugin-core-compatibility.md),
170
+ and `protocolVersion` is **not** bumped for it — a recorded, narrowly scoped
171
+ exemption on the same grounds as `system.capabilities.milestone`'s (#206),
172
+ written up under "Changing this contract" in
173
+ [`docs/protocol/mcp-tools.md`](../../docs/protocol/mcp-tools.md).
174
+
15
175
  ## [0.1.0.dev7] - 2026-08-19
16
176
 
17
177
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: theurian
3
- Version: 0.1.0.dev7
3
+ Version: 0.1.0.dev8
4
4
  Summary: Git-native engineering knowledge platform: versioned, traceable context for AI agents.
5
5
  Project-URL: Homepage, https://github.com/theurian/theurian
6
6
  Project-URL: Documentation, https://github.com/theurian/theurian/tree/main/docs
@@ -22,6 +22,7 @@ Requires-Dist: jsonschema==4.26.0
22
22
  Requires-Dist: pydantic==2.13.4
23
23
  Requires-Dist: python-ulid==4.0.1
24
24
  Requires-Dist: pyyaml==6.0.3
25
+ Requires-Dist: referencing==0.37.0
25
26
  Requires-Dist: typer==0.27.1
26
27
  Provides-Extra: all
27
28
  Requires-Dist: mcp==2.0.0; extra == 'all'
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "theurian"
7
- version = "0.1.0.dev7"
7
+ version = "0.1.0.dev8"
8
8
  description = "Git-native engineering knowledge platform: versioned, traceable context for AI agents."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -36,6 +36,11 @@ dependencies = [
36
36
  "pydantic==2.13.4",
37
37
  "python-ulid==4.0.1",
38
38
  "pyyaml==6.0.3",
39
+ # jsonschema's public reference-resolution API, imported directly for the
40
+ # no-network registry that keeps the installed migration schema offline
41
+ # (issue #235). A transitive dep of jsonschema, declared here because we
42
+ # import it -- ADR-0014's "import what you declare".
43
+ "referencing==0.37.0",
39
44
  "typer==0.27.1",
40
45
  ]
41
46
 
@@ -8,7 +8,7 @@ plugin must never import them (ADR-0001, CP-2).
8
8
 
9
9
  from theurian.domain.compatibility import CURRENT_PROTOCOL_VERSION
10
10
 
11
- __version__ = "0.1.0.dev7"
11
+ __version__ = "0.1.0.dev8"
12
12
  __protocol_version__ = CURRENT_PROTOCOL_VERSION
13
13
 
14
14
  __all__ = ["__protocol_version__", "__version__"]