ouroboros-ai 0.27.3.dev1__tar.gz → 0.27.3.dev3__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.

Potentially problematic release.


This version of ouroboros-ai might be problematic. Click here for more details.

Files changed (648) hide show
  1. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/PKG-INFO +27 -17
  2. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/README.ko.md +2 -0
  3. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/README.md +3 -1
  4. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/cli-reference.md +0 -4
  5. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/getting-started.md +2 -1
  6. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/pyproject.toml +17 -11
  7. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/_version.py +2 -2
  8. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/mcp.py +30 -11
  9. ouroboros_ai-0.27.3.dev3/src/ouroboros/cli/formatters/prompting.py +38 -0
  10. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/config/loader.py +20 -1
  11. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/file_lock.py +5 -5
  12. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/server/adapter.py +60 -7
  13. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/mcp_tools.py +2 -1
  14. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/session.py +84 -1
  15. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/event_store.py +158 -1
  16. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/litellm_adapter.py +12 -0
  17. ouroboros_ai-0.27.3.dev3/tests/unit/cli/formatters/test_prompting.py +45 -0
  18. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_mcp_startup_cleanup.py +124 -2
  19. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/config/test_loader_env.py +16 -0
  20. ouroboros_ai-0.27.3.dev3/tests/unit/core/test_file_lock.py +52 -0
  21. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/server/test_adapter.py +29 -0
  22. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_session.py +33 -0
  23. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/persistence/test_event_store.py +58 -0
  24. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_litellm_adapter.py +20 -0
  25. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_dependencies_configured.py +19 -0
  26. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/uv.lock +506 -17
  27. ouroboros_ai-0.27.3.dev1/src/ouroboros/cli/formatters/prompting.py +0 -68
  28. ouroboros_ai-0.27.3.dev1/tests/unit/cli/formatters/test_prompting.py +0 -32
  29. ouroboros_ai-0.27.3.dev1/tests/unit/core/test_file_lock.py +0 -17
  30. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.claude/settings.json +0 -0
  31. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.claude-plugin/.mcp.json +0 -0
  32. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.claude-plugin/marketplace.json +0 -0
  33. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.claude-plugin/plugin.json +0 -0
  34. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.env.example +0 -0
  35. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  36. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  37. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  38. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  39. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/workflows/dev-publish.yml +0 -0
  40. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/workflows/lint.yml +0 -0
  41. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/workflows/release.yml +0 -0
  42. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.github/workflows/test.yml +0 -0
  43. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.gitignore +0 -0
  44. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.mcp.json +0 -0
  45. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.ouroboros/mechanical.toml +0 -0
  46. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.ouroboros/seeds/seed_73827177a2a3.yaml +0 -0
  47. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.ouroboros/seeds/seed_78c8e6e41813.yaml +0 -0
  48. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.pre-commit-config.yaml +0 -0
  49. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/.python-version +0 -0
  50. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/CHANGELOG.md +0 -0
  51. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/CLAUDE.md +0 -0
  52. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/CODE_OF_CONDUCT.md +0 -0
  53. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/CONTRIBUTING.md +0 -0
  54. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/HANDOFF.md +0 -0
  55. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/LICENSE +0 -0
  56. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/SECURITY.md +0 -0
  57. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/UNINSTALL.md +0 -0
  58. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/cancel.md +0 -0
  59. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/evaluate.md +0 -0
  60. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/evolve.md +0 -0
  61. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/help.md +0 -0
  62. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/interview.md +0 -0
  63. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/ralph.md +0 -0
  64. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/run.md +0 -0
  65. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/seed.md +0 -0
  66. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/setup.md +0 -0
  67. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/status.md +0 -0
  68. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/tutorial.md +0 -0
  69. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/unstuck.md +0 -0
  70. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/commands/welcome.md +0 -0
  71. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/.gitignore +0 -0
  72. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/Cargo.lock +0 -0
  73. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/Cargo.toml +0 -0
  74. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/README.md +0 -0
  75. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/db.rs +0 -0
  76. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/main.rs +0 -0
  77. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/mock.rs +0 -0
  78. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/state.rs +0 -0
  79. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
  80. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/views/execution.rs +0 -0
  81. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
  82. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/views/logs.rs +0 -0
  83. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/views/mod.rs +0 -0
  84. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
  85. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/README.md +0 -0
  86. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/api/README.md +0 -0
  87. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/api/core.md +0 -0
  88. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/api/mcp.md +0 -0
  89. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/architecture.md +0 -0
  90. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/config-reference.md +0 -0
  91. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/contributing/architecture-overview.md +0 -0
  92. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/contributing/findings-registry.md +0 -0
  93. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/contributing/issue-quality-policy.md +0 -0
  94. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/contributing/key-patterns.md +0 -0
  95. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/contributing/testing-guide.md +0 -0
  96. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/examples/mcp-config.yaml +0 -0
  97. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/guides/evaluation-pipeline.md +0 -0
  98. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/guides/evolution-loop.md +0 -0
  99. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
  100. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/guides/mcp-bridge.md +0 -0
  101. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/guides/seed-authoring.md +0 -0
  102. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/guides/tui-usage.md +0 -0
  103. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/images/PLACEHOLDER_README.md +0 -0
  104. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/images/ouroboros.png +0 -0
  105. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/platform-support.md +0 -0
  106. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/runtime-capability-matrix.md +0 -0
  107. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/runtime-guides/claude-code.md +0 -0
  108. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/runtime-guides/codex.md +0 -0
  109. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/docs/runtime-guides/opencode.md +0 -0
  110. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/coordinator_test_seed.yaml +0 -0
  111. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/dummy_seed.yaml +0 -0
  112. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/parallel_subac_test_seed.yaml +0 -0
  113. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/subac_test_seed.yaml +0 -0
  114. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/task_manager/README.md +0 -0
  115. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/task_manager/__init__.py +0 -0
  116. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/task_manager/__main__.py +0 -0
  117. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/task_manager/cli.py +0 -0
  118. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/task_manager/models.py +0 -0
  119. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/task_manager/storage.py +0 -0
  120. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/examples/test_display.py +0 -0
  121. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/hooks/hooks.json +0 -0
  122. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/llms-full.txt +0 -0
  123. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/llms.txt +0 -0
  124. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/project-context.md +0 -0
  125. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/drift-monitor.py +0 -0
  126. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/install.sh +0 -0
  127. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/keyword-detector.py +0 -0
  128. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/mcp-serve.sh +0 -0
  129. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/ralph-rewind.py +0 -0
  130. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/ralph.py +0 -0
  131. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/ralph.sh +0 -0
  132. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/session-start.py +0 -0
  133. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/sync-plugin-version.py +0 -0
  134. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/scripts/version-check.py +0 -0
  135. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/brownfield/SKILL.md +0 -0
  136. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/cancel/SKILL.md +0 -0
  137. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/evaluate/SKILL.md +0 -0
  138. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/evolve/SKILL.md +0 -0
  139. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/help/SKILL.md +0 -0
  140. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/interview/SKILL.md +0 -0
  141. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/pm/SKILL.md +0 -0
  142. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/publish/SKILL.md +0 -0
  143. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/qa/SKILL.md +0 -0
  144. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/ralph/SKILL.md +0 -0
  145. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/run/SKILL.md +0 -0
  146. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/seed/SKILL.md +0 -0
  147. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/setup/SKILL.md +0 -0
  148. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/status/SKILL.md +0 -0
  149. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/tutorial/SKILL.md +0 -0
  150. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/unstuck/SKILL.md +0 -0
  151. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/update/SKILL.md +0 -0
  152. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/skills/welcome/SKILL.md +0 -0
  153. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/__init__.py +0 -0
  154. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/__main__.py +0 -0
  155. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/__init__.py +0 -0
  156. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/advocate.md +0 -0
  157. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/analysis-agent.md +0 -0
  158. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/architect.md +0 -0
  159. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/breadth-keeper.md +0 -0
  160. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/code-executor.md +0 -0
  161. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/codebase-explorer.md +0 -0
  162. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/consensus-reviewer.md +0 -0
  163. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/contrarian.md +0 -0
  164. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/evaluator.md +0 -0
  165. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/hacker.md +0 -0
  166. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/judge.md +0 -0
  167. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/loader.py +0 -0
  168. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/ontologist.md +0 -0
  169. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/ontology-analyst.md +0 -0
  170. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/qa-judge.md +0 -0
  171. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/research-agent.md +0 -0
  172. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/researcher.md +0 -0
  173. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/seed-architect.md +0 -0
  174. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/seed-closer.md +0 -0
  175. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/semantic-evaluator.md +0 -0
  176. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/simplifier.md +0 -0
  177. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/agents/socratic-interviewer.md +0 -0
  178. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/__init__.py +0 -0
  179. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/ambiguity.py +0 -0
  180. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/brownfield.py +0 -0
  181. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/explore.py +0 -0
  182. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/interview.py +0 -0
  183. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/pm_completion.py +0 -0
  184. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/pm_document.py +0 -0
  185. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/pm_interview.py +0 -0
  186. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/pm_seed.py +0 -0
  187. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/question_classifier.py +0 -0
  188. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/bigbang/seed_generator.py +0 -0
  189. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/__init__.py +0 -0
  190. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/__init__.py +0 -0
  191. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/cancel.py +0 -0
  192. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/config.py +0 -0
  193. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/init.py +0 -0
  194. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/pm.py +0 -0
  195. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/run.py +0 -0
  196. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/setup.py +0 -0
  197. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/status.py +0 -0
  198. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/tui.py +0 -0
  199. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/commands/uninstall.py +0 -0
  200. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/formatters/__init__.py +0 -0
  201. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/formatters/panels.py +0 -0
  202. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/formatters/progress.py +0 -0
  203. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/formatters/tables.py +0 -0
  204. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
  205. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/jsonc.py +0 -0
  206. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/cli/main.py +0 -0
  207. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/codex/__init__.py +0 -0
  208. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/codex/artifacts.py +0 -0
  209. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/codex/ouroboros.md +0 -0
  210. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/codex_permissions.py +0 -0
  211. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/config/__init__.py +0 -0
  212. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/config/models.py +0 -0
  213. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/__init__.py +0 -0
  214. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/ac_tree.py +0 -0
  215. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/context.py +0 -0
  216. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/errors.py +0 -0
  217. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/git_workflow.py +0 -0
  218. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/initial_context.py +0 -0
  219. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/json_utils.py +0 -0
  220. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/lineage.py +0 -0
  221. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/ontology_aspect.py +0 -0
  222. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/ontology_questions.py +0 -0
  223. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/project_paths.py +0 -0
  224. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/retry.py +0 -0
  225. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/security.py +0 -0
  226. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/seed.py +0 -0
  227. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/text.py +0 -0
  228. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/ttl_cache.py +0 -0
  229. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/types.py +0 -0
  230. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/core/worktree.py +0 -0
  231. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/__init__.py +0 -0
  232. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/artifact_collector.py +0 -0
  233. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/consensus.py +0 -0
  234. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/json_utils.py +0 -0
  235. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/languages.py +0 -0
  236. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/mechanical.py +0 -0
  237. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/models.py +0 -0
  238. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/pipeline.py +0 -0
  239. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/semantic.py +0 -0
  240. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/trigger.py +0 -0
  241. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
  242. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/__init__.py +0 -0
  243. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/base.py +0 -0
  244. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/decomposition.py +0 -0
  245. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/evaluation.py +0 -0
  246. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/interview.py +0 -0
  247. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/lineage.py +0 -0
  248. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/events/ontology.py +0 -0
  249. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/__init__.py +0 -0
  250. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/convergence.py +0 -0
  251. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/loop.py +0 -0
  252. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/projector.py +0 -0
  253. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/reflect.py +0 -0
  254. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/regression.py +0 -0
  255. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/evolution/wonder.py +0 -0
  256. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/execution/__init__.py +0 -0
  257. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/execution/atomicity.py +0 -0
  258. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/execution/decomposition.py +0 -0
  259. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/execution/double_diamond.py +0 -0
  260. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/execution/subagent.py +0 -0
  261. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/__init__.py +0 -0
  262. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/bridge/__init__.py +0 -0
  263. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/bridge/bridge.py +0 -0
  264. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/bridge/config.py +0 -0
  265. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/bridge/factory.py +0 -0
  266. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/client/__init__.py +0 -0
  267. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/client/adapter.py +0 -0
  268. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/client/manager.py +0 -0
  269. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/client/protocol.py +0 -0
  270. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/errors.py +0 -0
  271. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/job_manager.py +0 -0
  272. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/resources/__init__.py +0 -0
  273. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/resources/handlers.py +0 -0
  274. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/server/__init__.py +0 -0
  275. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/server/protocol.py +0 -0
  276. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/server/security.py +0 -0
  277. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/__init__.py +0 -0
  278. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/ac_tree_hud_handler.py +0 -0
  279. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/ac_tree_hud_render.py +0 -0
  280. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
  281. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/bridge_mixin.py +0 -0
  282. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
  283. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/dashboard.py +0 -0
  284. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/definitions.py +0 -0
  285. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
  286. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
  287. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
  288. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
  289. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/pm_handler.py +0 -0
  290. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/qa.py +0 -0
  291. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
  292. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/tools/registry.py +0 -0
  293. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/mcp/types.py +0 -0
  294. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/observability/__init__.py +0 -0
  295. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/observability/drift.py +0 -0
  296. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/observability/logging.py +0 -0
  297. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/observability/retrospective.py +0 -0
  298. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/__init__.py +0 -0
  299. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/adapter.py +0 -0
  300. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/capabilities.py +0 -0
  301. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
  302. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
  303. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/control_plane.py +0 -0
  304. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/coordinator.py +0 -0
  305. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
  306. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/events.py +0 -0
  307. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
  308. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
  309. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/heartbeat.py +0 -0
  310. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/level_context.py +0 -0
  311. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/mcp_config.py +0 -0
  312. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/opencode_event_normalizer.py +0 -0
  313. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/opencode_runtime.py +0 -0
  314. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
  315. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
  316. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/policy.py +0 -0
  317. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/runner.py +0 -0
  318. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
  319. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
  320. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/orchestrator/workflow_state.py +0 -0
  321. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/__init__.py +0 -0
  322. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/brownfield.py +0 -0
  323. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/checkpoint.py +0 -0
  324. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/migrations/__init__.py +0 -0
  325. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/migrations/runner.py +0 -0
  326. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
  327. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
  328. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/schema.py +0 -0
  329. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/persistence/uow.py +0 -0
  330. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/__init__.py +0 -0
  331. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/agents/__init__.py +0 -0
  332. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/agents/pool.py +0 -0
  333. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/agents/registry.py +0 -0
  334. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
  335. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/orchestration/router.py +0 -0
  336. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
  337. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/skills/__init__.py +0 -0
  338. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/skills/docs.py +0 -0
  339. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/skills/executor.py +0 -0
  340. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/skills/keywords.py +0 -0
  341. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/plugin/skills/registry.py +0 -0
  342. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/pm/__init__.py +0 -0
  343. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/pm/handoff.py +0 -0
  344. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/pm/renderer.py +0 -0
  345. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/__init__.py +0 -0
  346. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/anthropic_adapter.py +0 -0
  347. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/base.py +0 -0
  348. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/claude_code_adapter.py +0 -0
  349. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/codex_cli_adapter.py +0 -0
  350. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/codex_cli_stream.py +0 -0
  351. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/factory.py +0 -0
  352. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/gemini_cli_adapter.py +0 -0
  353. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/providers/opencode_adapter.py +0 -0
  354. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/py.typed +0 -0
  355. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/resilience/__init__.py +0 -0
  356. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/resilience/lateral.py +0 -0
  357. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/resilience/stagnation.py +0 -0
  358. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/routing/__init__.py +0 -0
  359. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/routing/complexity.py +0 -0
  360. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/routing/downgrade.py +0 -0
  361. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/routing/escalation.py +0 -0
  362. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/routing/router.py +0 -0
  363. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/routing/tiers.py +0 -0
  364. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/secondary/__init__.py +0 -0
  365. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/secondary/scheduler.py +0 -0
  366. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/secondary/todo_registry.py +0 -0
  367. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/strategies/__init__.py +0 -0
  368. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/strategies/devil_advocate.py +0 -0
  369. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/__init__.py +0 -0
  370. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/app.py +0 -0
  371. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/components/__init__.py +0 -0
  372. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/components/agents_panel.py +0 -0
  373. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/components/event_log.py +0 -0
  374. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/components/progress.py +0 -0
  375. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/components/token_tracker.py +0 -0
  376. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/events.py +0 -0
  377. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/__init__.py +0 -0
  378. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
  379. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/dashboard.py +0 -0
  380. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
  381. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
  382. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/debug.py +0 -0
  383. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/execution.py +0 -0
  384. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
  385. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
  386. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
  387. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/logs.py +0 -0
  388. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/screens/session_selector.py +0 -0
  389. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/__init__.py +0 -0
  390. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
  391. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
  392. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
  393. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
  394. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
  395. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
  396. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
  397. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
  398. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/verification/__init__.py +0 -0
  399. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/verification/extractor.py +0 -0
  400. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/verification/models.py +0 -0
  401. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/src/ouroboros/verification/verifier.py +0 -0
  402. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/__init__.py +0 -0
  403. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/conftest.py +0 -0
  404. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/e2e/__init__.py +0 -0
  405. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/e2e/conftest.py +0 -0
  406. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/e2e/mcp_bridge_test_config.yaml +0 -0
  407. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/e2e/test_cli_commands.py +0 -0
  408. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/e2e/test_full_workflow.py +0 -0
  409. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/e2e/test_session_persistence.py +0 -0
  410. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/fixtures/test_atomicity_seed.yml +0 -0
  411. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/__init__.py +0 -0
  412. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/conftest.py +0 -0
  413. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/__init__.py +0 -0
  414. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/bridge/__init__.py +0 -0
  415. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/bridge/test_bridge_server_to_server.py +0 -0
  416. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/conftest.py +0 -0
  417. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/test_client_adapter.py +0 -0
  418. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/test_client_manager.py +0 -0
  419. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/mcp/test_server_adapter.py +0 -0
  420. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/plugin/test_orchestration.py +0 -0
  421. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
  422. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/test_codex_skill_fallback.py +0 -0
  423. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/test_codex_skill_smoke.py +0 -0
  424. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/integration/test_entry_point.py +0 -0
  425. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/__init__.py +0 -0
  426. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/agents/__init__.py +0 -0
  427. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/agents/test_loader.py +0 -0
  428. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/__init__.py +0 -0
  429. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_ambiguity.py +0 -0
  430. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_brownfield.py +0 -0
  431. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_classifier_context.py +0 -0
  432. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_decide_later_items.py +0 -0
  433. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_explore.py +0 -0
  434. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_interview.py +0 -0
  435. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_interview_async_io.py +0 -0
  436. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_interview_no_web_search_hint.py +0 -0
  437. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_interview_research_prefix.py +0 -0
  438. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_completion.py +0 -0
  439. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
  440. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
  441. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_interview.py +0 -0
  442. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
  443. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
  444. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
  445. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_question_classifier.py +0 -0
  446. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/bigbang/test_seed_generator.py +0 -0
  447. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/__init__.py +0 -0
  448. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/commands/test_tui_command.py +0 -0
  449. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/formatters/__init__.py +0 -0
  450. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/formatters/test_console.py +0 -0
  451. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/formatters/test_panels.py +0 -0
  452. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/formatters/test_progress.py +0 -0
  453. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/formatters/test_tables.py +0 -0
  454. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
  455. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_cancel.py +0 -0
  456. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_config.py +0 -0
  457. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_init_pm_seed_detection.py +0 -0
  458. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_init_runtime.py +0 -0
  459. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_jsonc.py +0 -0
  460. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_main.py +0 -0
  461. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
  462. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm.py +0 -0
  463. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_brownfield.py +0 -0
  464. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_completion.py +0 -0
  465. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_interactive_logging.py +0 -0
  466. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
  467. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_overwrite.py +0 -0
  468. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_runtime_adapter.py +0 -0
  469. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_pm_select_repos.py +0 -0
  470. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_run_qa.py +0 -0
  471. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_setup.py +0 -0
  472. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/cli/test_uninstall.py +0 -0
  473. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/config/__init__.py +0 -0
  474. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/config/test_loader.py +0 -0
  475. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/config/test_models.py +0 -0
  476. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/__init__.py +0 -0
  477. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_ac_tree.py +0 -0
  478. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_context.py +0 -0
  479. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_errors.py +0 -0
  480. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_git_workflow.py +0 -0
  481. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_initial_context.py +0 -0
  482. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_lineage.py +0 -0
  483. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_ontology_aspect.py +0 -0
  484. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_ontology_questions.py +0 -0
  485. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_retry.py +0 -0
  486. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_security.py +0 -0
  487. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_seed.py +0 -0
  488. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_ttl_cache.py +0 -0
  489. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_types.py +0 -0
  490. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/core/test_worktree.py +0 -0
  491. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/__init__.py +0 -0
  492. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_artifact_collector_file_prefix.py +0 -0
  493. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_consensus.py +0 -0
  494. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_json_utils.py +0 -0
  495. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_languages.py +0 -0
  496. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_mechanical.py +0 -0
  497. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_models.py +0 -0
  498. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_pipeline_trigger_consensus.py +0 -0
  499. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_review_fixes.py +0 -0
  500. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_semantic.py +0 -0
  501. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_trigger.py +0 -0
  502. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_trigger_consensus.py +0 -0
  503. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
  504. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/events/__init__.py +0 -0
  505. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/events/test_base.py +0 -0
  506. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/events/test_decomposition_events.py +0 -0
  507. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/evolution/test_wonder_scope.py +0 -0
  508. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/execution/__init__.py +0 -0
  509. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/execution/test_atomicity.py +0 -0
  510. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/execution/test_decomposition.py +0 -0
  511. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/execution/test_double_diamond.py +0 -0
  512. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/execution/test_subagent_isolation.py +0 -0
  513. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/__init__.py +0 -0
  514. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/bridge/__init__.py +0 -0
  515. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/bridge/test_bridge.py +0 -0
  516. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/bridge/test_config.py +0 -0
  517. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/bridge/test_factory.py +0 -0
  518. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/bridge/test_handler_wiring.py +0 -0
  519. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/bridge/test_stability.py +0 -0
  520. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/client/__init__.py +0 -0
  521. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/client/test_adapter.py +0 -0
  522. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/client/test_adapter_transport_lifecycle.py +0 -0
  523. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/client/test_manager.py +0 -0
  524. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/conftest.py +0 -0
  525. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/server/__init__.py +0 -0
  526. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/server/test_security.py +0 -0
  527. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/test_errors.py +0 -0
  528. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/test_job_manager.py +0 -0
  529. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/test_types.py +0 -0
  530. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/__init__.py +0 -0
  531. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/conftest.py +0 -0
  532. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_footer.py +0 -0
  533. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_handler.py +0 -0
  534. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_handler_completed.py +0 -0
  535. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_handler_cursor_changed.py +0 -0
  536. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_handler_invalid_session.py +0 -0
  537. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_handler_no_execution.py +0 -0
  538. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_handler_waiting.py +0 -0
  539. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_max_nodes.py +0 -0
  540. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_render_depth2.py +0 -0
  541. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_render_depth3.py +0 -0
  542. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_status_icons.py +0 -0
  543. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_ac_tree_hud_truncation.py +0 -0
  544. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
  545. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_definitions.py +0 -0
  546. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_evaluation_handler.py +0 -0
  547. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_interview_parallel_scoring.py +0 -0
  548. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_interview_scoring_guard.py +0 -0
  549. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_mcp_manager_wiring.py +0 -0
  550. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_pm_handler.py +0 -0
  551. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_pm_handler_generate.py +0 -0
  552. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
  553. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
  554. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_qa_parser.py +0 -0
  555. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_registry.py +0 -0
  556. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/mcp/tools/test_traceback_reporting.py +0 -0
  557. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/observability/__init__.py +0 -0
  558. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/observability/test_drift.py +0 -0
  559. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/observability/test_logging.py +0 -0
  560. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/observability/test_retrospective.py +0 -0
  561. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/__init__.py +0 -0
  562. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_adapter.py +0 -0
  563. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_capabilities.py +0 -0
  564. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
  565. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
  566. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
  567. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_control_plane.py +0 -0
  568. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_coordinator.py +0 -0
  569. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
  570. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_events.py +0 -0
  571. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
  572. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
  573. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
  574. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_level_context.py +0 -0
  575. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_mcp_config.py +0 -0
  576. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
  577. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_opencode_runtime.py +0 -0
  578. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
  579. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_parallel_executor_atomic_judgment.py +0 -0
  580. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_parallel_executor_recursive_depth.py +0 -0
  581. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
  582. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_policy.py +0 -0
  583. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_runner.py +0 -0
  584. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
  585. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
  586. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
  587. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/orchestrator/test_workflow_state.py +0 -0
  588. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/persistence/__init__.py +0 -0
  589. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/persistence/test_brownfield_store.py +0 -0
  590. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/persistence/test_checkpoint.py +0 -0
  591. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/persistence/test_schema.py +0 -0
  592. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/persistence/test_uow.py +0 -0
  593. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/__init__.py +0 -0
  594. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/agents/__init__.py +0 -0
  595. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/agents/test_registry.py +0 -0
  596. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/orchestration/__init__.py +0 -0
  597. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
  598. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/skills/__init__.py +0 -0
  599. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/skills/test_keywords.py +0 -0
  600. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/plugin/skills/test_registry.py +0 -0
  601. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/pm/__init__.py +0 -0
  602. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/pm/test_renderer.py +0 -0
  603. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/__init__.py +0 -0
  604. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_base.py +0 -0
  605. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_claude_code_adapter.py +0 -0
  606. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_codex_cli_adapter.py +0 -0
  607. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_factory.py +0 -0
  608. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_gemini_cli_adapter.py +0 -0
  609. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/providers/test_opencode_adapter.py +0 -0
  610. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/resilience/__init__.py +0 -0
  611. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/resilience/test_lateral.py +0 -0
  612. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/resilience/test_stagnation.py +0 -0
  613. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/routing/__init__.py +0 -0
  614. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/routing/test_complexity.py +0 -0
  615. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/routing/test_downgrade.py +0 -0
  616. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/routing/test_escalation.py +0 -0
  617. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/routing/test_router.py +0 -0
  618. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/routing/test_tiers.py +0 -0
  619. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/scripts/test_keyword_detector.py +0 -0
  620. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/scripts/test_version_check.py +0 -0
  621. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/secondary/__init__.py +0 -0
  622. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/secondary/test_scheduler.py +0 -0
  623. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/secondary/test_todo_registry.py +0 -0
  624. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_artifact_collector.py +0 -0
  625. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_codex_artifacts.py +0 -0
  626. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_convergence.py +0 -0
  627. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_dashboard.py +0 -0
  628. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_evolve_rewind.py +0 -0
  629. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_evolve_step.py +0 -0
  630. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_graceful_shutdown.py +0 -0
  631. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_main_entry_point.py +0 -0
  632. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_module_structure.py +0 -0
  633. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_project_initialization.py +0 -0
  634. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_projector_rewind.py +0 -0
  635. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_ralph_parser.py +0 -0
  636. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_ralph_rewind.py +0 -0
  637. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_regression.py +0 -0
  638. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_tooling_configuration.py +0 -0
  639. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/test_verification.py +0 -0
  640. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/__init__.py +0 -0
  641. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_app.py +0 -0
  642. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_cancelled_display.py +0 -0
  643. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_events.py +0 -0
  644. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_lineage_viewer.py +0 -0
  645. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_screens.py +0 -0
  646. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_session_selector_replay.py +0 -0
  647. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tests/unit/tui/test_widgets.py +0 -0
  648. {ouroboros_ai-0.27.3.dev1 → ouroboros_ai-0.27.3.dev3}/tools/sync_github_project.py +0 -0
@@ -1,32 +1,40 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ouroboros-ai
3
- Version: 0.27.3.dev1
3
+ Version: 0.27.3.dev3
4
4
  Summary: Specification-first workflow engine for AI coding agents. Works with Claude Code and Codex CLI.
5
5
  Author-email: Q00 <jqyu.lee@gmail.com>
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.12
8
- Requires-Dist: aiosqlite>=0.20.0
9
- Requires-Dist: pydantic>=2.0.0
10
- Requires-Dist: pyyaml>=6.0.0
11
- Requires-Dist: rich>=13.0.0
12
- Requires-Dist: sqlalchemy[asyncio]>=2.0.0
13
- Requires-Dist: structlog>=24.0.0
14
- Requires-Dist: typer>=0.12.0
8
+ Requires-Dist: aiosqlite<1.0.0,>=0.20.0
9
+ Requires-Dist: prompt-toolkit<4.0.0,>=3.0.0
10
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
11
+ Requires-Dist: pyyaml<7.0.0,>=6.0.0
12
+ Requires-Dist: rich<15.0.0,>=13.0.0
13
+ Requires-Dist: sqlalchemy[asyncio]<3.0.0,>=2.0.0
14
+ Requires-Dist: structlog<26.0.0,>=24.0.0
15
+ Requires-Dist: typer<1.0.0,>=0.12.0
15
16
  Provides-Extra: all
16
- Requires-Dist: anthropic>=0.52.0; extra == 'all'
17
- Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'all'
17
+ Requires-Dist: anthropic<1.0.0,>=0.52.0; extra == 'all'
18
+ Requires-Dist: claude-agent-sdk<1.0.0,>=0.1.0; extra == 'all'
18
19
  Requires-Dist: litellm<=1.82.6,>=1.80.0; extra == 'all'
19
- Requires-Dist: mcp>=1.26.0; extra == 'all'
20
- Requires-Dist: textual>=1.0.0; extra == 'all'
20
+ Requires-Dist: mcp<2.0.0,>=1.26.0; extra == 'all'
21
+ Requires-Dist: pandas<3.0.0,>=2.2.0; extra == 'all'
22
+ Requires-Dist: plotly<7.0.0,>=5.24.0; extra == 'all'
23
+ Requires-Dist: streamlit<2.0.0,>=1.40.0; extra == 'all'
24
+ Requires-Dist: textual<9.0.0,>=1.0.0; extra == 'all'
21
25
  Provides-Extra: claude
22
- Requires-Dist: anthropic>=0.52.0; extra == 'claude'
23
- Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'claude'
26
+ Requires-Dist: anthropic<1.0.0,>=0.52.0; extra == 'claude'
27
+ Requires-Dist: claude-agent-sdk<1.0.0,>=0.1.0; extra == 'claude'
28
+ Provides-Extra: dashboard
29
+ Requires-Dist: pandas<3.0.0,>=2.2.0; extra == 'dashboard'
30
+ Requires-Dist: plotly<7.0.0,>=5.24.0; extra == 'dashboard'
31
+ Requires-Dist: streamlit<2.0.0,>=1.40.0; extra == 'dashboard'
24
32
  Provides-Extra: litellm
25
33
  Requires-Dist: litellm<=1.82.6,>=1.80.0; extra == 'litellm'
26
34
  Provides-Extra: mcp
27
- Requires-Dist: mcp>=1.26.0; extra == 'mcp'
35
+ Requires-Dist: mcp<2.0.0,>=1.26.0; extra == 'mcp'
28
36
  Provides-Extra: tui
29
- Requires-Dist: textual>=1.0.0; extra == 'tui'
37
+ Requires-Dist: textual<9.0.0,>=1.0.0; extra == 'tui'
30
38
  Description-Content-Type: text/markdown
31
39
 
32
40
  <p align="right">
@@ -128,10 +136,12 @@ pip install ouroboros-ai[claude] # + Claude Code deps
128
136
  pip install ouroboros-ai[litellm] # + LiteLLM multi-provider
129
137
  pip install ouroboros-ai[mcp] # + MCP server/client support
130
138
  pip install ouroboros-ai[tui] # + Textual terminal UI
131
- pip install ouroboros-ai[all] # everything
139
+ pip install ouroboros-ai[all] # everything (claude + litellm + mcp + tui + dashboard)
132
140
  ouroboros setup # configure runtime
133
141
  ```
134
142
 
143
+ Legacy compatibility: `ouroboros-ai[dashboard]` is still accepted as a compatibility alias while extras migrate.
144
+
135
145
  See runtime guides: [Claude Code](./docs/runtime-guides/claude-code.md) · [Codex CLI](./docs/runtime-guides/codex.md)
136
146
 
137
147
  </details>
@@ -125,6 +125,8 @@ pip install ouroboros-ai[all] # 전부
125
125
  ouroboros setup # 런타임 설정
126
126
  ```
127
127
 
128
+ 호환성 참고: extras 전환 기간 동안 `ouroboros-ai[dashboard]`도 no-op alias로 계속 허용됩니다.
129
+
128
130
  런타임별 가이드: [Claude Code](./docs/runtime-guides/claude-code.md) · [Codex CLI](./docs/runtime-guides/codex.md)
129
131
 
130
132
  </details>
@@ -97,10 +97,12 @@ pip install ouroboros-ai[claude] # + Claude Code deps
97
97
  pip install ouroboros-ai[litellm] # + LiteLLM multi-provider
98
98
  pip install ouroboros-ai[mcp] # + MCP server/client support
99
99
  pip install ouroboros-ai[tui] # + Textual terminal UI
100
- pip install ouroboros-ai[all] # everything
100
+ pip install ouroboros-ai[all] # everything (claude + litellm + mcp + tui + dashboard)
101
101
  ouroboros setup # configure runtime
102
102
  ```
103
103
 
104
+ Legacy compatibility: `ouroboros-ai[dashboard]` is still accepted as a compatibility alias while extras migrate.
105
+
104
106
  See runtime guides: [Claude Code](./docs/runtime-guides/claude-code.md) · [Codex CLI](./docs/runtime-guides/codex.md)
105
107
 
106
108
  </details>
@@ -160,10 +160,6 @@ ouroboros init start --resume interview_20260116_120000
160
160
  ouroboros init
161
161
  ```
162
162
 
163
- > **Interactive multiline input:** when `init` or other interview-style commands prompt for a
164
- > longer response, press `Ctrl+D` (macOS/Linux) or `Ctrl+Z` then Enter (Windows) to submit the
165
- > full response. Plain Enter inserts a newline.
166
-
167
163
  ### `init list`
168
164
 
169
165
  List all interview sessions.
@@ -82,13 +82,14 @@ pip install ouroboros-ai[claude] # + Claude Code runtime deps (anthropic, c
82
82
  pip install ouroboros-ai[litellm] # + LiteLLM multi-provider support (100+ models)
83
83
  pip install ouroboros-ai[mcp] # + MCP server/client runtime support
84
84
  pip install ouroboros-ai[tui] # + Textual terminal UI
85
- pip install ouroboros-ai[all] # Everything (claude + litellm + mcp + tui)
85
+ pip install ouroboros-ai[all] # Everything (claude + litellm + mcp + tui + dashboard)
86
86
 
87
87
  ouroboros --version # verify CLI
88
88
  ```
89
89
 
90
90
  > **Which extra do I need?** If you only use Claude Code as your runtime, `ouroboros-ai[claude]` is sufficient.
91
91
  > For multi-model support via LiteLLM, use `ouroboros-ai[litellm]` or just grab everything with `ouroboros-ai[all]`.
92
+ > Legacy note: `ouroboros-ai[dashboard]` is still accepted as a compatibility extra during the extras transition.
92
93
 
93
94
  **One-liner alternative** (auto-detects your runtime and installs matching extras):
94
95
  ```bash
@@ -8,21 +8,27 @@ authors = [
8
8
  ]
9
9
  requires-python = ">=3.12"
10
10
  dependencies = [
11
- "aiosqlite>=0.20.0",
12
- "pydantic>=2.0.0",
13
- "pyyaml>=6.0.0",
14
- "rich>=13.0.0",
15
- "sqlalchemy[asyncio]>=2.0.0",
16
- "structlog>=24.0.0",
17
- "typer>=0.12.0",
11
+ "aiosqlite>=0.20.0,<1.0.0",
12
+ "pydantic>=2.0.0,<3.0.0",
13
+ "prompt-toolkit>=3.0.0,<4.0.0",
14
+ "pyyaml>=6.0.0,<7.0.0",
15
+ "rich>=13.0.0,<15.0.0",
16
+ "sqlalchemy[asyncio]>=2.0.0,<3.0.0",
17
+ "structlog>=24.0.0,<26.0.0",
18
+ "typer>=0.12.0,<1.0.0",
18
19
  ]
19
20
 
20
21
  [project.optional-dependencies]
21
- claude = ["claude-agent-sdk>=0.1.0", "anthropic>=0.52.0"]
22
+ claude = ["claude-agent-sdk>=0.1.0,<1.0.0", "anthropic>=0.52.0,<1.0.0"]
22
23
  litellm = ["litellm>=1.80.0,<=1.82.6"]
23
- mcp = ["mcp>=1.26.0"]
24
- tui = ["textual>=1.0.0"]
25
- all = ["ouroboros-ai[claude,litellm,mcp,tui]"]
24
+ dashboard = [
25
+ "streamlit>=1.40.0,<2.0.0",
26
+ "plotly>=5.24.0,<7.0.0",
27
+ "pandas>=2.2.0,<3.0.0",
28
+ ]
29
+ mcp = ["mcp>=1.26.0,<2.0.0"]
30
+ tui = ["textual>=1.0.0,<9.0.0"]
31
+ all = ["ouroboros-ai[claude,litellm,mcp,tui,dashboard]"]
26
32
 
27
33
  [project.scripts]
28
34
  ouroboros = "ouroboros.cli.main:app"
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.27.3.dev1'
22
- __version_tuple__ = version_tuple = (0, 27, 3, 'dev1')
21
+ __version__ = version = '0.27.3.dev3'
22
+ __version_tuple__ = version_tuple = (0, 27, 3, 'dev3')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -140,22 +140,35 @@ async def _run_mcp_server(
140
140
  else:
141
141
  event_store = EventStore()
142
142
 
143
- # Auto-cancel orphaned sessions on startup.
144
- # Sessions left in RUNNING/PAUSED state for >1 hour are considered orphaned
145
- # (e.g., from a previous crash). Cancel them before accepting new requests.
146
- # NOTE: find_orphaned_sessions now checks for active runtime processes first,
147
- # so sessions with live claude/codex agents won't be cancelled even if stale.
143
+ cleanup_task: asyncio.Task[None] | None = None
144
+
145
+ # Initialize the event store up front because the MCP server uses it for
146
+ # request handling. Orphan cleanup is intentionally deferred into the
147
+ # background so large SQLite histories do not block the initial MCP
148
+ # handshake on startup (#304).
148
149
  try:
149
150
  await event_store.initialize()
150
- repo = SessionRepository(event_store)
151
- cancelled = await repo.cancel_orphaned_sessions()
152
- if cancelled:
153
- _stderr_console.print(
154
- f"[yellow]Auto-cancelled {len(cancelled)} orphaned session(s)[/yellow]"
155
- )
156
151
  except Exception as e:
157
152
  # Auto-cleanup is best-effort — don't prevent server from starting
158
153
  _stderr_console.print(f"[yellow]Warning: auto-cleanup failed: {e}[/yellow]")
154
+ else:
155
+ repo = SessionRepository(event_store)
156
+
157
+ async def _run_startup_cleanup() -> None:
158
+ try:
159
+ cancelled = await repo.cancel_orphaned_sessions()
160
+ if cancelled:
161
+ _stderr_console.print(
162
+ f"[yellow]Auto-cancelled {len(cancelled)} orphaned session(s)[/yellow]"
163
+ )
164
+ except Exception as e:
165
+ # Auto-cleanup is best-effort — don't prevent server startup
166
+ _stderr_console.print(f"[yellow]Warning: auto-cleanup failed: {e}[/yellow]")
167
+
168
+ cleanup_task = asyncio.create_task(
169
+ _run_startup_cleanup(),
170
+ name="ouroboros-mcp-startup-cleanup",
171
+ )
159
172
 
160
173
  # Auto-discover and connect MCP bridge for server-to-server communication
161
174
  from ouroboros.mcp.bridge import create_bridge_from_env
@@ -224,6 +237,12 @@ async def _run_mcp_server(
224
237
  try:
225
238
  await server.serve(transport=transport, host=host, port=port)
226
239
  finally:
240
+ if cleanup_task is not None and not cleanup_task.done():
241
+ cleanup_task.cancel()
242
+ try:
243
+ await cleanup_task
244
+ except asyncio.CancelledError:
245
+ pass
227
246
  _cleanup_pid_file()
228
247
 
229
248
 
@@ -0,0 +1,38 @@
1
+ """Prompt helpers for interactive CLI input."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from prompt_toolkit import PromptSession
6
+ from prompt_toolkit.key_binding import KeyBindings, KeyPressEvent
7
+ from prompt_toolkit.patch_stdout import patch_stdout
8
+
9
+ from ouroboros.cli.formatters import console
10
+
11
+
12
+ async def multiline_prompt_async(prompt_text: str) -> str:
13
+ """Get multiline-safe input while allowing logs above the active prompt."""
14
+ bindings = KeyBindings()
15
+
16
+ @bindings.add("c-j")
17
+ def insert_newline(event: KeyPressEvent) -> None:
18
+ event.current_buffer.insert_text("\n")
19
+
20
+ @bindings.add("c-m")
21
+ def submit(event: KeyPressEvent) -> None:
22
+ event.current_buffer.validate_and_handle()
23
+
24
+ console.print(f"[bold green]{prompt_text}[/] [dim](Enter: submit, Ctrl+J: newline)[/]")
25
+
26
+ session: PromptSession[str] = PromptSession(
27
+ message="> ",
28
+ multiline=True,
29
+ prompt_continuation=" ",
30
+ key_bindings=bindings,
31
+ )
32
+
33
+ # prompt_toolkit proxies both stdout and stderr above the prompt.
34
+ with patch_stdout(raw=True):
35
+ return await session.prompt_async()
36
+
37
+
38
+ __all__ = ["multiline_prompt_async"]
@@ -54,6 +54,8 @@ from ouroboros.core.errors import ConfigError # noqa: E402
54
54
  _CODEX_LLM_BACKENDS = frozenset({"codex", "codex_cli", "opencode", "opencode_cli"})
55
55
  _OPENCODE_BACKENDS = frozenset({"opencode", "opencode_cli"})
56
56
  _CODEX_DEFAULT_MODEL = "default"
57
+ _PLACEHOLDER_API_KEY_PREFIX = "YOUR_"
58
+ _PLACEHOLDER_API_KEY_SUFFIX = "_API_KEY"
57
59
  _DEFAULT_CONSENSUS_MODELS = (
58
60
  "openrouter/openai/gpt-4o",
59
61
  "openrouter/anthropic/claude-opus-4-6",
@@ -82,6 +84,16 @@ def _parse_env_value(raw_value: str) -> str:
82
84
  return candidate.rstrip()
83
85
 
84
86
 
87
+ def _is_placeholder_api_key(value: str) -> bool:
88
+ """Treat common template placeholders as unset."""
89
+ candidate = value.strip()
90
+ return bool(
91
+ candidate
92
+ and candidate.startswith(_PLACEHOLDER_API_KEY_PREFIX)
93
+ and candidate.endswith(_PLACEHOLDER_API_KEY_SUFFIX)
94
+ )
95
+
96
+
85
97
  def _load_env_file(path: Path) -> None:
86
98
  if not path.exists():
87
99
  return
@@ -99,7 +111,14 @@ def _load_env_file(path: Path) -> None:
99
111
  key = key.strip()
100
112
  if not key or any(ch.isspace() for ch in key):
101
113
  continue
102
- os.environ.setdefault(key, _parse_env_value(raw_value))
114
+
115
+ parsed_value = _parse_env_value(raw_value)
116
+ if not parsed_value or _is_placeholder_api_key(parsed_value):
117
+ continue
118
+
119
+ current_value = os.environ.get(key)
120
+ if current_value is None or _is_placeholder_api_key(current_value):
121
+ os.environ[key] = parsed_value
103
122
 
104
123
 
105
124
  for env_path in (Path(".env"), Path.home() / ".ouroboros" / ".env"):
@@ -15,14 +15,14 @@ else: # pragma: no branch
15
15
 
16
16
 
17
17
  @contextmanager
18
- def file_lock(file_path: Path, exclusive: bool = True) -> Iterator[None]: # noqa: ARG001
18
+ def file_lock(file_path: Path, exclusive: bool = True) -> Iterator[None]:
19
19
  """Context manager for cross-platform file locking."""
20
20
  lock_path = file_path.with_suffix(file_path.suffix + ".lock")
21
21
  lock_path.parent.mkdir(parents=True, exist_ok=True)
22
22
 
23
23
  with lock_path.open("a+", encoding="utf-8") as handle:
24
24
  _ensure_lockfile_content(handle)
25
- _acquire_lock(handle)
25
+ _acquire_lock(handle, exclusive=exclusive)
26
26
  try:
27
27
  yield
28
28
  finally:
@@ -37,13 +37,13 @@ def _ensure_lockfile_content(handle: TextIO) -> None:
37
37
  handle.seek(0)
38
38
 
39
39
 
40
- def _acquire_lock(handle: TextIO) -> None:
40
+ def _acquire_lock(handle: TextIO, *, exclusive: bool = True) -> None:
41
41
  if os.name == "nt": # pragma: no cover - exercised on Windows
42
42
  handle.seek(0)
43
- msvcrt.locking(handle.fileno(), msvcrt.LK_LOCK, 1)
43
+ msvcrt.locking(handle.fileno(), msvcrt.LK_RLCK if not exclusive else msvcrt.LK_LOCK, 1)
44
44
  return
45
45
 
46
- fcntl.flock(handle.fileno(), fcntl.LOCK_EX)
46
+ fcntl.flock(handle.fileno(), fcntl.LOCK_EX if exclusive else fcntl.LOCK_SH)
47
47
 
48
48
 
49
49
  def _release_lock(handle: TextIO) -> None:
@@ -8,8 +8,10 @@ handling, and server lifecycle.
8
8
  import asyncio
9
9
  from collections.abc import Sequence
10
10
  import inspect
11
+ import keyword
11
12
  import os
12
13
  from pathlib import Path
14
+ import re
13
15
  from typing import Any
14
16
 
15
17
  import structlog
@@ -105,13 +107,50 @@ def _build_tool_signature(parameters: tuple[MCPToolParameter, ...]) -> inspect.S
105
107
  By setting __signature__ with explicit parameters, FastMCP generates the
106
108
  correct schema and clients can send flat argument dicts.
107
109
  """
110
+ signature, _ = _build_tool_signature_with_aliases(parameters)
111
+ return signature
112
+
113
+
114
+ def _to_safe_signature_name(name: str) -> str:
115
+ """Return a valid Python identifier for a tool parameter name."""
116
+ if name.isidentifier() and not keyword.iskeyword(name):
117
+ return name
118
+
119
+ # Replace invalid characters with underscore and avoid starting with a digit.
120
+ sanitized = re.sub(r"[^0-9a-zA-Z_]", "_", name)
121
+ sanitized = re.sub(r"_+", "_", sanitized).strip("_")
122
+ if not sanitized or sanitized[0].isdigit():
123
+ sanitized = f"_{sanitized or 'param'}"
124
+
125
+ if keyword.iskeyword(sanitized):
126
+ sanitized = f"_{sanitized}"
127
+
128
+ return sanitized
129
+
130
+
131
+ def _build_tool_signature_with_aliases(
132
+ parameters: tuple[MCPToolParameter, ...],
133
+ ) -> tuple[inspect.Signature, dict[str, str]]:
134
+ """Build signature plus map from schema args to original MCP parameter names."""
135
+
108
136
  sig_params = []
137
+ alias_counts: dict[str, int] = {}
138
+ alias_to_original: dict[str, str] = {}
139
+
109
140
  for p in parameters:
141
+ parameter_name = _to_safe_signature_name(p.name)
142
+ alias_count = alias_counts.get(parameter_name, 0) + 1
143
+ alias_counts[parameter_name] = alias_count
144
+ if alias_count > 1:
145
+ parameter_name = f"{parameter_name}_{alias_count}"
146
+
147
+ alias_to_original[parameter_name] = p.name
148
+
110
149
  python_type = _TOOL_TYPE_MAP.get(p.type, Any)
111
150
  if p.required:
112
151
  sig_params.append(
113
152
  inspect.Parameter(
114
- name=p.name,
153
+ name=parameter_name,
115
154
  kind=inspect.Parameter.KEYWORD_ONLY,
116
155
  annotation=python_type,
117
156
  )
@@ -120,13 +159,14 @@ def _build_tool_signature(parameters: tuple[MCPToolParameter, ...]) -> inspect.S
120
159
  default = p.default if p.default is not None else None
121
160
  sig_params.append(
122
161
  inspect.Parameter(
123
- name=p.name,
162
+ name=parameter_name,
124
163
  kind=inspect.Parameter.KEYWORD_ONLY,
125
164
  default=default,
126
165
  annotation=python_type | None,
127
166
  )
128
167
  )
129
- return inspect.Signature(parameters=sig_params)
168
+
169
+ return inspect.Signature(parameters=sig_params), alias_to_original
130
170
 
131
171
 
132
172
  _PROJECT_ROOT_MARKERS = (
@@ -200,11 +240,13 @@ def _project_dir_from_artifact(artifact: str) -> str | None:
200
240
  from pathlib import Path
201
241
  import re
202
242
 
203
- # Match quoted paths (spaces allowed) or unquoted paths (no spaces).
243
+ # Match quoted paths (spaces allowed) and unquoted paths.
204
244
  # Examples: Write: /foo/bar.py | File: "/path with spaces/bar.py"
205
245
  write_matches: list[str] = []
206
- for m in re.finditer(r'(?:Write|Edit|File): (?:"([^"]+)"|(/[^\s]+))', artifact):
207
- write_matches.append(m.group(1) or m.group(2))
246
+ for m in re.finditer(r'(?:Write|Edit|File): (?:"([^"]+)"|(.+))', artifact):
247
+ path_candidate = m.group(1) or m.group(2)
248
+ if path_candidate:
249
+ write_matches.append(path_candidate.strip())
208
250
  for path_str in write_matches:
209
251
  candidate = Path(path_str).parent
210
252
  for _ in range(10):
@@ -529,7 +571,18 @@ class MCPServerAdapter:
529
571
  and isinstance(kwargs["kwargs"], dict)
530
572
  ):
531
573
  kwargs = kwargs["kwargs"]
532
- result = await h.handle(kwargs)
574
+
575
+ _, alias_to_original = _build_tool_signature_with_aliases(
576
+ h.definition.parameters,
577
+ )
578
+ normalized_kwargs: dict[str, Any] = {}
579
+ for alias_key, original_key in alias_to_original.items():
580
+ if alias_key in kwargs:
581
+ normalized_kwargs[original_key] = kwargs[alias_key]
582
+ for key, value in kwargs.items():
583
+ normalized_kwargs.setdefault(key, value)
584
+
585
+ result = await h.handle(normalized_kwargs)
533
586
  if result.is_ok:
534
587
  # Convert MCPToolResult to FastMCP format
535
588
  tool_result = result.value
@@ -2059,6 +2059,7 @@ class MCPToolProvider:
2059
2059
 
2060
2060
  try:
2061
2061
  # Retry transient failures with bounded backoff
2062
+ # Use retry_async for retries on transient failures
2062
2063
  result = await self._call_with_retry(
2063
2064
  tool_info=tool_info,
2064
2065
  arguments=arguments or {},
@@ -2090,7 +2091,7 @@ class MCPToolProvider:
2090
2091
  ) -> Result[MCPToolResult, MCPToolError]:
2091
2092
  """Call tool with retry logic for transient failures.
2092
2093
 
2093
- Uses internal exponential backoff retries on:
2094
+ Uses retry_async for exponential backoff retries on:
2094
2095
  - Connection errors
2095
2096
  - Timeout errors (if marked retriable)
2096
2097
  - Other transient MCPClientErrors
@@ -34,7 +34,7 @@ from ouroboros.events.base import BaseEvent, sanitize_event_data_for_persistence
34
34
  from ouroboros.observability.logging import get_logger
35
35
 
36
36
  if TYPE_CHECKING:
37
- from ouroboros.persistence.event_store import EventStore
37
+ from ouroboros.persistence.event_store import EventStore, SessionActivitySnapshot
38
38
 
39
39
  log = get_logger(__name__)
40
40
 
@@ -352,6 +352,70 @@ class SessionRepository:
352
352
 
353
353
  return progress
354
354
 
355
+ @staticmethod
356
+ def _coerce_snapshot_datetime(value: object) -> datetime | None:
357
+ """Normalize timestamp values returned by snapshot queries."""
358
+ if isinstance(value, datetime):
359
+ if value.tzinfo is None:
360
+ return value.replace(tzinfo=UTC)
361
+ return value
362
+ if isinstance(value, str) and value:
363
+ parsed = datetime.fromisoformat(value)
364
+ if parsed.tzinfo is None:
365
+ return parsed.replace(tzinfo=UTC)
366
+ return parsed
367
+ return None
368
+
369
+ @classmethod
370
+ def _status_from_snapshot(cls, snapshot: SessionActivitySnapshot) -> SessionStatus:
371
+ """Derive session status from a snapshot row."""
372
+ status = cls._status_from_event(snapshot.status_event_type, {})
373
+ if status is not None:
374
+ return status
375
+
376
+ runtime_status = cls._coerce_runtime_status(snapshot.runtime_status)
377
+ if runtime_status is not None:
378
+ return runtime_status
379
+
380
+ return SessionStatus.RUNNING
381
+
382
+ async def _find_orphaned_sessions_via_snapshots(
383
+ self,
384
+ snapshots: list[SessionActivitySnapshot],
385
+ alive_sessions: set[str],
386
+ staleness_threshold: timedelta,
387
+ now: datetime,
388
+ ) -> list[SessionTracker]:
389
+ """Detect orphaned sessions from pre-aggregated session snapshots."""
390
+ orphaned: list[SessionTracker] = []
391
+
392
+ for snapshot in snapshots:
393
+ status = self._status_from_snapshot(snapshot)
394
+ if status not in (SessionStatus.RUNNING, SessionStatus.PAUSED):
395
+ continue
396
+
397
+ if snapshot.session_id in alive_sessions:
398
+ log.info(
399
+ "orchestrator.orphan_detection.heartbeat_alive",
400
+ session_id=snapshot.session_id,
401
+ )
402
+ continue
403
+
404
+ last_activity = self._coerce_snapshot_datetime(snapshot.last_activity)
405
+ if last_activity is None:
406
+ last_activity = self._coerce_snapshot_datetime(snapshot.start_time)
407
+ if last_activity is None:
408
+ continue
409
+
410
+ if (now - last_activity) <= staleness_threshold:
411
+ continue
412
+
413
+ result = await self.reconstruct_session(snapshot.session_id)
414
+ if result.is_ok:
415
+ orphaned.append(result.value)
416
+
417
+ return orphaned
418
+
355
419
  @staticmethod
356
420
  def _merge_event_streams(
357
421
  primary_events: list[BaseEvent],
@@ -892,6 +956,24 @@ class SessionRepository:
892
956
  orphaned: list[SessionTracker] = []
893
957
 
894
958
  try:
959
+ get_snapshots = getattr(self._event_store, "get_session_activity_snapshots", None)
960
+ if callable(get_snapshots):
961
+ snapshots = await get_snapshots()
962
+ if isinstance(snapshots, list):
963
+ orphaned = await self._find_orphaned_sessions_via_snapshots(
964
+ snapshots,
965
+ alive_sessions,
966
+ staleness_threshold,
967
+ now,
968
+ )
969
+ log.info(
970
+ "orchestrator.orphan_detection.complete",
971
+ total_sessions=len(snapshots),
972
+ orphaned_count=len(orphaned),
973
+ strategy="snapshot",
974
+ )
975
+ return orphaned
976
+
895
977
  # Get all session start events to enumerate sessions
896
978
  start_events = await self._event_store.get_all_sessions()
897
979
 
@@ -955,6 +1037,7 @@ class SessionRepository:
955
1037
  "orchestrator.orphan_detection.complete",
956
1038
  total_sessions=len(start_events),
957
1039
  orphaned_count=len(orphaned),
1040
+ strategy="replay",
958
1041
  )
959
1042
 
960
1043
  except Exception as e: