ouroboros-ai 0.26.5.dev6__tar.gz → 0.26.5.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.

Potentially problematic release.


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

Files changed (573) hide show
  1. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/PKG-INFO +1 -1
  2. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/pm/SKILL.md +5 -1
  3. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/_version.py +2 -2
  4. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/init.py +17 -7
  5. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/pm.py +43 -0
  6. ouroboros_ai-0.26.5.dev8/src/ouroboros/core/initial_context.py +209 -0
  7. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/authoring_handlers.py +12 -2
  8. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/pm_handler.py +13 -3
  9. ouroboros_ai-0.26.5.dev8/src/ouroboros/pm/handoff.py +18 -0
  10. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/claude_code_adapter.py +44 -8
  11. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/codex_cli_adapter.py +14 -4
  12. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/factory.py +10 -1
  13. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_init_pm_seed_detection.py +34 -0
  14. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_completion.py +14 -4
  15. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_overwrite.py +81 -1
  16. ouroboros_ai-0.26.5.dev8/tests/unit/core/test_initial_context.py +117 -0
  17. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_definitions.py +46 -0
  18. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_pm_handler_generate.py +45 -4
  19. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/providers/test_claude_code_adapter.py +63 -0
  20. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/providers/test_codex_cli_adapter.py +20 -0
  21. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/providers/test_factory.py +35 -0
  22. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.claude/settings.json +0 -0
  23. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.claude-plugin/.mcp.json +0 -0
  24. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.claude-plugin/marketplace.json +0 -0
  25. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.claude-plugin/plugin.json +0 -0
  26. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.env.example +0 -0
  27. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  28. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  29. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  30. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  31. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/workflows/dev-publish.yml +0 -0
  32. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/workflows/lint.yml +0 -0
  33. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/workflows/release.yml +0 -0
  34. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.github/workflows/test.yml +0 -0
  35. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.gitignore +0 -0
  36. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.mcp.json +0 -0
  37. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.ouroboros/mechanical.toml +0 -0
  38. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.pre-commit-config.yaml +0 -0
  39. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/.python-version +0 -0
  40. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/CHANGELOG.md +0 -0
  41. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/CLAUDE.md +0 -0
  42. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/CODE_OF_CONDUCT.md +0 -0
  43. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/CONTRIBUTING.md +0 -0
  44. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/HANDOFF.md +0 -0
  45. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/LICENSE +0 -0
  46. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/README.ko.md +0 -0
  47. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/README.md +0 -0
  48. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/SECURITY.md +0 -0
  49. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/UNINSTALL.md +0 -0
  50. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/cancel.md +0 -0
  51. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/evaluate.md +0 -0
  52. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/evolve.md +0 -0
  53. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/help.md +0 -0
  54. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/interview.md +0 -0
  55. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/ralph.md +0 -0
  56. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/run.md +0 -0
  57. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/seed.md +0 -0
  58. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/setup.md +0 -0
  59. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/status.md +0 -0
  60. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/tutorial.md +0 -0
  61. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/unstuck.md +0 -0
  62. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/commands/welcome.md +0 -0
  63. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/.gitignore +0 -0
  64. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/Cargo.lock +0 -0
  65. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/Cargo.toml +0 -0
  66. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/README.md +0 -0
  67. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/db.rs +0 -0
  68. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/main.rs +0 -0
  69. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/mock.rs +0 -0
  70. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/state.rs +0 -0
  71. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
  72. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/views/execution.rs +0 -0
  73. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
  74. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/views/logs.rs +0 -0
  75. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/views/mod.rs +0 -0
  76. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
  77. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/README.md +0 -0
  78. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/api/README.md +0 -0
  79. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/api/core.md +0 -0
  80. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/api/mcp.md +0 -0
  81. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/architecture.md +0 -0
  82. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/cli-reference.md +0 -0
  83. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/config-reference.md +0 -0
  84. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/contributing/architecture-overview.md +0 -0
  85. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/contributing/findings-registry.md +0 -0
  86. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/contributing/issue-quality-policy.md +0 -0
  87. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/contributing/key-patterns.md +0 -0
  88. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/contributing/testing-guide.md +0 -0
  89. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/examples/mcp-config.yaml +0 -0
  90. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/getting-started.md +0 -0
  91. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/guides/evaluation-pipeline.md +0 -0
  92. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/guides/evolution-loop.md +0 -0
  93. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
  94. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/guides/seed-authoring.md +0 -0
  95. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/guides/tui-usage.md +0 -0
  96. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/images/PLACEHOLDER_README.md +0 -0
  97. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/images/ouroboros.png +0 -0
  98. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/platform-support.md +0 -0
  99. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/runtime-capability-matrix.md +0 -0
  100. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/runtime-guides/claude-code.md +0 -0
  101. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/docs/runtime-guides/codex.md +0 -0
  102. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/coordinator_test_seed.yaml +0 -0
  103. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/dummy_seed.yaml +0 -0
  104. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/parallel_subac_test_seed.yaml +0 -0
  105. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/subac_test_seed.yaml +0 -0
  106. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/task_manager/README.md +0 -0
  107. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/task_manager/__init__.py +0 -0
  108. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/task_manager/__main__.py +0 -0
  109. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/task_manager/cli.py +0 -0
  110. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/task_manager/models.py +0 -0
  111. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/task_manager/storage.py +0 -0
  112. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/examples/test_display.py +0 -0
  113. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/hooks/hooks.json +0 -0
  114. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/llms-full.txt +0 -0
  115. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/llms.txt +0 -0
  116. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/project-context.md +0 -0
  117. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/pyproject.toml +0 -0
  118. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/drift-monitor.py +0 -0
  119. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/install.sh +0 -0
  120. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/keyword-detector.py +0 -0
  121. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/mcp-serve.sh +0 -0
  122. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/ralph-rewind.py +0 -0
  123. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/ralph.py +0 -0
  124. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/ralph.sh +0 -0
  125. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/session-start.py +0 -0
  126. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/sync-plugin-version.py +0 -0
  127. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/scripts/version-check.py +0 -0
  128. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/brownfield/SKILL.md +0 -0
  129. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/cancel/SKILL.md +0 -0
  130. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/evaluate/SKILL.md +0 -0
  131. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/evolve/SKILL.md +0 -0
  132. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/help/SKILL.md +0 -0
  133. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/interview/SKILL.md +0 -0
  134. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/qa/SKILL.md +0 -0
  135. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/ralph/SKILL.md +0 -0
  136. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/run/SKILL.md +0 -0
  137. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/seed/SKILL.md +0 -0
  138. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/setup/SKILL.md +0 -0
  139. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/status/SKILL.md +0 -0
  140. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/tutorial/SKILL.md +0 -0
  141. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/unstuck/SKILL.md +0 -0
  142. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/update/SKILL.md +0 -0
  143. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/skills/welcome/SKILL.md +0 -0
  144. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/__init__.py +0 -0
  145. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/__main__.py +0 -0
  146. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/__init__.py +0 -0
  147. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/advocate.md +0 -0
  148. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/analysis-agent.md +0 -0
  149. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/architect.md +0 -0
  150. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/breadth-keeper.md +0 -0
  151. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/code-executor.md +0 -0
  152. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/codebase-explorer.md +0 -0
  153. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/consensus-reviewer.md +0 -0
  154. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/contrarian.md +0 -0
  155. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/evaluator.md +0 -0
  156. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/hacker.md +0 -0
  157. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/judge.md +0 -0
  158. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/loader.py +0 -0
  159. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/ontologist.md +0 -0
  160. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/ontology-analyst.md +0 -0
  161. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/qa-judge.md +0 -0
  162. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/research-agent.md +0 -0
  163. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/researcher.md +0 -0
  164. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/seed-architect.md +0 -0
  165. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/seed-closer.md +0 -0
  166. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/semantic-evaluator.md +0 -0
  167. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/simplifier.md +0 -0
  168. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/agents/socratic-interviewer.md +0 -0
  169. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/__init__.py +0 -0
  170. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/ambiguity.py +0 -0
  171. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/brownfield.py +0 -0
  172. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/explore.py +0 -0
  173. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/interview.py +0 -0
  174. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/pm_completion.py +0 -0
  175. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/pm_document.py +0 -0
  176. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/pm_interview.py +0 -0
  177. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/pm_seed.py +0 -0
  178. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/question_classifier.py +0 -0
  179. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/bigbang/seed_generator.py +0 -0
  180. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/__init__.py +0 -0
  181. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/__init__.py +0 -0
  182. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/cancel.py +0 -0
  183. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/config.py +0 -0
  184. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/mcp.py +0 -0
  185. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/run.py +0 -0
  186. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/setup.py +0 -0
  187. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/status.py +0 -0
  188. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/tui.py +0 -0
  189. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/commands/uninstall.py +0 -0
  190. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/formatters/__init__.py +0 -0
  191. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/formatters/panels.py +0 -0
  192. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/formatters/progress.py +0 -0
  193. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/formatters/prompting.py +0 -0
  194. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/formatters/tables.py +0 -0
  195. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
  196. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/cli/main.py +0 -0
  197. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/codex/__init__.py +0 -0
  198. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/codex/artifacts.py +0 -0
  199. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/codex/ouroboros.md +0 -0
  200. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/codex_permissions.py +0 -0
  201. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/config/__init__.py +0 -0
  202. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/config/loader.py +0 -0
  203. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/config/models.py +0 -0
  204. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/__init__.py +0 -0
  205. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/ac_tree.py +0 -0
  206. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/context.py +0 -0
  207. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/errors.py +0 -0
  208. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/file_lock.py +0 -0
  209. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/git_workflow.py +0 -0
  210. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/lineage.py +0 -0
  211. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/ontology_aspect.py +0 -0
  212. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/ontology_questions.py +0 -0
  213. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/project_paths.py +0 -0
  214. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/security.py +0 -0
  215. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/seed.py +0 -0
  216. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/text.py +0 -0
  217. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/types.py +0 -0
  218. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/core/worktree.py +0 -0
  219. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/__init__.py +0 -0
  220. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/artifact_collector.py +0 -0
  221. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/consensus.py +0 -0
  222. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/json_utils.py +0 -0
  223. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/languages.py +0 -0
  224. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/mechanical.py +0 -0
  225. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/models.py +0 -0
  226. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/pipeline.py +0 -0
  227. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/semantic.py +0 -0
  228. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/trigger.py +0 -0
  229. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
  230. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/__init__.py +0 -0
  231. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/base.py +0 -0
  232. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/decomposition.py +0 -0
  233. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/evaluation.py +0 -0
  234. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/interview.py +0 -0
  235. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/lineage.py +0 -0
  236. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/events/ontology.py +0 -0
  237. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/__init__.py +0 -0
  238. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/convergence.py +0 -0
  239. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/loop.py +0 -0
  240. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/projector.py +0 -0
  241. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/reflect.py +0 -0
  242. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/regression.py +0 -0
  243. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/evolution/wonder.py +0 -0
  244. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/execution/__init__.py +0 -0
  245. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/execution/atomicity.py +0 -0
  246. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/execution/decomposition.py +0 -0
  247. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/execution/double_diamond.py +0 -0
  248. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/execution/subagent.py +0 -0
  249. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/__init__.py +0 -0
  250. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/client/__init__.py +0 -0
  251. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/client/adapter.py +0 -0
  252. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/client/manager.py +0 -0
  253. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/client/protocol.py +0 -0
  254. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/errors.py +0 -0
  255. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/job_manager.py +0 -0
  256. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/resources/__init__.py +0 -0
  257. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/resources/handlers.py +0 -0
  258. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/server/__init__.py +0 -0
  259. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/server/adapter.py +0 -0
  260. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/server/protocol.py +0 -0
  261. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/server/security.py +0 -0
  262. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/__init__.py +0 -0
  263. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
  264. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/dashboard.py +0 -0
  265. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/definitions.py +0 -0
  266. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
  267. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
  268. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
  269. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
  270. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/qa.py +0 -0
  271. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
  272. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/tools/registry.py +0 -0
  273. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/mcp/types.py +0 -0
  274. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/observability/__init__.py +0 -0
  275. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/observability/drift.py +0 -0
  276. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/observability/logging.py +0 -0
  277. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/observability/retrospective.py +0 -0
  278. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/__init__.py +0 -0
  279. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/adapter.py +0 -0
  280. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
  281. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
  282. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/coordinator.py +0 -0
  283. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
  284. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/events.py +0 -0
  285. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
  286. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
  287. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/heartbeat.py +0 -0
  288. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/level_context.py +0 -0
  289. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/mcp_config.py +0 -0
  290. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
  291. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
  292. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
  293. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/runner.py +0 -0
  294. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
  295. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
  296. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/session.py +0 -0
  297. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/orchestrator/workflow_state.py +0 -0
  298. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/__init__.py +0 -0
  299. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/brownfield.py +0 -0
  300. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/checkpoint.py +0 -0
  301. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/event_store.py +0 -0
  302. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/migrations/__init__.py +0 -0
  303. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/migrations/runner.py +0 -0
  304. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
  305. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
  306. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/schema.py +0 -0
  307. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/persistence/uow.py +0 -0
  308. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/__init__.py +0 -0
  309. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/agents/__init__.py +0 -0
  310. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/agents/pool.py +0 -0
  311. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/agents/registry.py +0 -0
  312. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
  313. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/orchestration/router.py +0 -0
  314. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
  315. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/skills/__init__.py +0 -0
  316. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/skills/docs.py +0 -0
  317. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/skills/executor.py +0 -0
  318. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/skills/keywords.py +0 -0
  319. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/plugin/skills/registry.py +0 -0
  320. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/pm/__init__.py +0 -0
  321. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/pm/renderer.py +0 -0
  322. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/__init__.py +0 -0
  323. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/anthropic_adapter.py +0 -0
  324. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/base.py +0 -0
  325. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/codex_cli_stream.py +0 -0
  326. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/providers/litellm_adapter.py +0 -0
  327. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/py.typed +0 -0
  328. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/resilience/__init__.py +0 -0
  329. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/resilience/lateral.py +0 -0
  330. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/resilience/stagnation.py +0 -0
  331. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/routing/__init__.py +0 -0
  332. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/routing/complexity.py +0 -0
  333. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/routing/downgrade.py +0 -0
  334. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/routing/escalation.py +0 -0
  335. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/routing/router.py +0 -0
  336. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/routing/tiers.py +0 -0
  337. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/secondary/__init__.py +0 -0
  338. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/secondary/scheduler.py +0 -0
  339. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/secondary/todo_registry.py +0 -0
  340. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/strategies/__init__.py +0 -0
  341. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/strategies/devil_advocate.py +0 -0
  342. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/__init__.py +0 -0
  343. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/app.py +0 -0
  344. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/components/__init__.py +0 -0
  345. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/components/agents_panel.py +0 -0
  346. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/components/event_log.py +0 -0
  347. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/components/progress.py +0 -0
  348. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/components/token_tracker.py +0 -0
  349. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/events.py +0 -0
  350. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/__init__.py +0 -0
  351. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
  352. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/dashboard.py +0 -0
  353. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
  354. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
  355. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/debug.py +0 -0
  356. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/execution.py +0 -0
  357. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
  358. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
  359. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
  360. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/logs.py +0 -0
  361. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/screens/session_selector.py +0 -0
  362. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/__init__.py +0 -0
  363. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
  364. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
  365. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
  366. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
  367. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
  368. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
  369. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
  370. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
  371. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/verification/__init__.py +0 -0
  372. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/verification/extractor.py +0 -0
  373. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/verification/models.py +0 -0
  374. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/src/ouroboros/verification/verifier.py +0 -0
  375. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/__init__.py +0 -0
  376. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/conftest.py +0 -0
  377. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/e2e/__init__.py +0 -0
  378. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/e2e/conftest.py +0 -0
  379. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/e2e/test_cli_commands.py +0 -0
  380. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/e2e/test_full_workflow.py +0 -0
  381. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/e2e/test_session_persistence.py +0 -0
  382. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/fixtures/test_atomicity_seed.yml +0 -0
  383. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/__init__.py +0 -0
  384. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/conftest.py +0 -0
  385. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/mcp/__init__.py +0 -0
  386. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/mcp/conftest.py +0 -0
  387. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/mcp/test_client_adapter.py +0 -0
  388. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/mcp/test_client_manager.py +0 -0
  389. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/mcp/test_server_adapter.py +0 -0
  390. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/plugin/test_orchestration.py +0 -0
  391. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
  392. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/test_codex_skill_fallback.py +0 -0
  393. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/test_codex_skill_smoke.py +0 -0
  394. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/integration/test_entry_point.py +0 -0
  395. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/__init__.py +0 -0
  396. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/agents/__init__.py +0 -0
  397. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/agents/test_loader.py +0 -0
  398. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/__init__.py +0 -0
  399. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_ambiguity.py +0 -0
  400. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_brownfield.py +0 -0
  401. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_classifier_context.py +0 -0
  402. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_decide_later_items.py +0 -0
  403. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_explore.py +0 -0
  404. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_interview.py +0 -0
  405. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_completion.py +0 -0
  406. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
  407. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
  408. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_interview.py +0 -0
  409. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
  410. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
  411. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
  412. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_question_classifier.py +0 -0
  413. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/bigbang/test_seed_generator.py +0 -0
  414. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/__init__.py +0 -0
  415. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/__init__.py +0 -0
  416. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/test_console.py +0 -0
  417. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/test_panels.py +0 -0
  418. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/test_progress.py +0 -0
  419. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/test_prompting.py +0 -0
  420. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/test_tables.py +0 -0
  421. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
  422. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_cancel.py +0 -0
  423. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_config.py +0 -0
  424. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_init_runtime.py +0 -0
  425. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_main.py +0 -0
  426. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
  427. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
  428. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm.py +0 -0
  429. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_brownfield.py +0 -0
  430. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_interactive_logging.py +0 -0
  431. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
  432. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_runtime_adapter.py +0 -0
  433. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_pm_select_repos.py +0 -0
  434. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_run_qa.py +0 -0
  435. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_setup.py +0 -0
  436. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/cli/test_uninstall.py +0 -0
  437. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/config/__init__.py +0 -0
  438. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/config/test_loader.py +0 -0
  439. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/config/test_models.py +0 -0
  440. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/__init__.py +0 -0
  441. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_ac_tree.py +0 -0
  442. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_context.py +0 -0
  443. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_errors.py +0 -0
  444. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_git_workflow.py +0 -0
  445. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_lineage.py +0 -0
  446. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_ontology_aspect.py +0 -0
  447. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_ontology_questions.py +0 -0
  448. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_security.py +0 -0
  449. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_seed.py +0 -0
  450. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_types.py +0 -0
  451. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/core/test_worktree.py +0 -0
  452. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/__init__.py +0 -0
  453. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_consensus.py +0 -0
  454. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_json_utils.py +0 -0
  455. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_languages.py +0 -0
  456. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_mechanical.py +0 -0
  457. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_models.py +0 -0
  458. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_semantic.py +0 -0
  459. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_trigger.py +0 -0
  460. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
  461. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/events/__init__.py +0 -0
  462. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/events/test_base.py +0 -0
  463. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/events/test_decomposition_events.py +0 -0
  464. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/evolution/test_wonder_scope.py +0 -0
  465. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/execution/__init__.py +0 -0
  466. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/execution/test_atomicity.py +0 -0
  467. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/execution/test_decomposition.py +0 -0
  468. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/execution/test_double_diamond.py +0 -0
  469. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/execution/test_subagent_isolation.py +0 -0
  470. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/__init__.py +0 -0
  471. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/client/__init__.py +0 -0
  472. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/client/test_adapter.py +0 -0
  473. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/client/test_manager.py +0 -0
  474. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/conftest.py +0 -0
  475. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/server/__init__.py +0 -0
  476. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/server/test_adapter.py +0 -0
  477. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/server/test_security.py +0 -0
  478. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/test_errors.py +0 -0
  479. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/test_job_manager.py +0 -0
  480. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/test_types.py +0 -0
  481. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/__init__.py +0 -0
  482. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/conftest.py +0 -0
  483. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
  484. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_pm_handler.py +0 -0
  485. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
  486. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
  487. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/mcp/tools/test_registry.py +0 -0
  488. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/observability/__init__.py +0 -0
  489. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/observability/test_drift.py +0 -0
  490. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/observability/test_logging.py +0 -0
  491. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/observability/test_retrospective.py +0 -0
  492. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/__init__.py +0 -0
  493. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_adapter.py +0 -0
  494. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
  495. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
  496. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
  497. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_coordinator.py +0 -0
  498. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
  499. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_events.py +0 -0
  500. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
  501. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
  502. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
  503. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_level_context.py +0 -0
  504. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_mcp_config.py +0 -0
  505. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
  506. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
  507. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
  508. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_runner.py +0 -0
  509. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
  510. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
  511. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
  512. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_session.py +0 -0
  513. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/orchestrator/test_workflow_state.py +0 -0
  514. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/persistence/__init__.py +0 -0
  515. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/persistence/test_brownfield_store.py +0 -0
  516. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/persistence/test_checkpoint.py +0 -0
  517. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/persistence/test_event_store.py +0 -0
  518. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/persistence/test_schema.py +0 -0
  519. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/persistence/test_uow.py +0 -0
  520. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/__init__.py +0 -0
  521. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/agents/__init__.py +0 -0
  522. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/agents/test_registry.py +0 -0
  523. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/orchestration/__init__.py +0 -0
  524. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
  525. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/skills/__init__.py +0 -0
  526. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/skills/test_keywords.py +0 -0
  527. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/plugin/skills/test_registry.py +0 -0
  528. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/pm/__init__.py +0 -0
  529. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/pm/test_renderer.py +0 -0
  530. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/providers/__init__.py +0 -0
  531. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/providers/test_base.py +0 -0
  532. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/providers/test_litellm_adapter.py +0 -0
  533. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/resilience/__init__.py +0 -0
  534. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/resilience/test_lateral.py +0 -0
  535. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/resilience/test_stagnation.py +0 -0
  536. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/routing/__init__.py +0 -0
  537. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/routing/test_complexity.py +0 -0
  538. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/routing/test_downgrade.py +0 -0
  539. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/routing/test_escalation.py +0 -0
  540. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/routing/test_router.py +0 -0
  541. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/routing/test_tiers.py +0 -0
  542. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/scripts/test_keyword_detector.py +0 -0
  543. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/scripts/test_version_check.py +0 -0
  544. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/secondary/__init__.py +0 -0
  545. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/secondary/test_scheduler.py +0 -0
  546. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/secondary/test_todo_registry.py +0 -0
  547. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_artifact_collector.py +0 -0
  548. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_codex_artifacts.py +0 -0
  549. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_convergence.py +0 -0
  550. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_dashboard.py +0 -0
  551. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_dependencies_configured.py +0 -0
  552. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_evolve_rewind.py +0 -0
  553. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_evolve_step.py +0 -0
  554. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_graceful_shutdown.py +0 -0
  555. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_main_entry_point.py +0 -0
  556. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_module_structure.py +0 -0
  557. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_project_initialization.py +0 -0
  558. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_projector_rewind.py +0 -0
  559. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_ralph_parser.py +0 -0
  560. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_ralph_rewind.py +0 -0
  561. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_regression.py +0 -0
  562. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_tooling_configuration.py +0 -0
  563. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/test_verification.py +0 -0
  564. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/__init__.py +0 -0
  565. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_app.py +0 -0
  566. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_cancelled_display.py +0 -0
  567. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_events.py +0 -0
  568. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_lineage_viewer.py +0 -0
  569. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_screens.py +0 -0
  570. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_session_selector_replay.py +0 -0
  571. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tests/unit/tui/test_widgets.py +0 -0
  572. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/tools/sync_github_project.py +0 -0
  573. {ouroboros_ai-0.26.5.dev6 → ouroboros_ai-0.26.5.dev8}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ouroboros-ai
3
- Version: 0.26.5.dev6
3
+ Version: 0.26.5.dev8
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
@@ -120,6 +120,10 @@ Show the following to the user:
120
120
  PM document saved: <meta.pm_path>
121
121
  (Clipboard에 복사되었습니다)
122
122
 
123
+ PM seed handoff artifact: <meta.pm_seed_path or meta.seed_path>
124
+ This is not the runnable Seed yet.
125
+
123
126
  Next step:
124
- ooo interview <meta.pm_path>
127
+ ooo interview <meta.pm_seed_path or meta.seed_path>
128
+ ooo seed
125
129
  ```
@@ -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.26.5.dev6'
22
- __version_tuple__ = version_tuple = (0, 26, 5, 'dev6')
21
+ __version__ = version = '0.26.5.dev8'
22
+ __version_tuple__ = version_tuple = (0, 26, 5, 'dev8')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -26,6 +26,12 @@ from ouroboros.cli.formatters import console
26
26
  from ouroboros.cli.formatters.panels import print_error, print_info, print_success, print_warning
27
27
  from ouroboros.cli.formatters.prompting import multiline_prompt_async
28
28
  from ouroboros.config import get_clarification_model
29
+ from ouroboros.core.initial_context import (
30
+ load_pm_seed_as_context as _load_pm_seed_as_context_result,
31
+ )
32
+ from ouroboros.core.initial_context import (
33
+ resolve_initial_context_input,
34
+ )
29
35
  from ouroboros.observability import LoggingConfig, configure_logging
30
36
  from ouroboros.providers import create_llm_adapter
31
37
  from ouroboros.providers.base import LLMAdapter
@@ -619,13 +625,10 @@ def _load_pm_seed_as_context(seed_path: Path) -> str:
619
625
  Returns:
620
626
  YAML-formatted string for use as dev interview initial_context.
621
627
  """
622
- from ouroboros.bigbang.pm_seed import PMSeed
623
-
624
- with open(seed_path) as f:
625
- data = yaml.safe_load(f)
626
-
627
- pm_seed = PMSeed.from_dict(data)
628
- return pm_seed.to_initial_context()
628
+ result = _load_pm_seed_as_context_result(seed_path)
629
+ if result.is_err:
630
+ raise ValueError(str(result.error))
631
+ return result.value
629
632
 
630
633
 
631
634
  @app.command()
@@ -752,6 +755,13 @@ def start(
752
755
 
753
756
  context = asyncio.run(multiline_prompt_async("What would you like to build?"))
754
757
 
758
+ if context:
759
+ resolved_context = resolve_initial_context_input(context, cwd=Path.cwd())
760
+ if resolved_context.is_err:
761
+ print_error(str(resolved_context.error))
762
+ raise typer.Exit(code=1)
763
+ context = resolved_context.value
764
+
755
765
  if not resume and not context:
756
766
  print_error("Initial context is required when not resuming.")
757
767
  raise typer.Exit(code=1)
@@ -27,6 +27,7 @@ from ouroboros.cli.formatters.prompting import multiline_prompt_async
27
27
  from ouroboros.config import get_clarification_model, get_llm_backend
28
28
  from ouroboros.core.types import Result
29
29
  from ouroboros.observability import LoggingConfig, configure_logging
30
+ from ouroboros.pm.handoff import build_pm_dev_handoff_command
30
31
  from ouroboros.providers.factory import (
31
32
  create_llm_adapter,
32
33
  resolve_llm_backend,
@@ -384,6 +385,32 @@ def _make_message_callback(debug: bool):
384
385
  return callback
385
386
 
386
387
 
388
+ async def _continue_into_dev_interview(
389
+ seed_path: Path,
390
+ *,
391
+ debug: bool,
392
+ llm_backend: str | None,
393
+ ) -> None:
394
+ """Resolve a PM artifact path into interview context and start the dev interview."""
395
+ from ouroboros.cli.commands.init import _run_interview
396
+ from ouroboros.core.initial_context import resolve_initial_context_input
397
+
398
+ resolved_context = resolve_initial_context_input(str(seed_path), cwd=Path.cwd())
399
+ if resolved_context.is_err:
400
+ print_error(f"Failed to load PM seed for dev interview: {resolved_context.error.message}")
401
+ raise typer.Exit(code=1)
402
+
403
+ await _run_interview(
404
+ resolved_context.value,
405
+ resume_id=None,
406
+ state_dir=None,
407
+ use_orchestrator=False,
408
+ debug=debug,
409
+ workflow_runtime_backend=None,
410
+ llm_backend=llm_backend,
411
+ )
412
+
413
+
387
414
  async def _run_pm_interview(
388
415
  resume_id: str | None,
389
416
  model: str,
@@ -667,6 +694,22 @@ async def _run_pm_interview(
667
694
  pm_dir = Path(output_dir) if output_dir else Path.cwd() / ".ouroboros"
668
695
  pm_path = save_pm_document(seed, output_dir=pm_dir)
669
696
  print_success(f"PM document saved: {pm_path}")
697
+
698
+ print_info(
699
+ "The PM seed is a handoff artifact for the dev interview, not the runnable Seed."
700
+ )
701
+ print_info(f"Next: {build_pm_dev_handoff_command(seed_path)}")
702
+
703
+ continue_to_dev = Confirm.ask(
704
+ "Continue into the dev interview now?",
705
+ default=True,
706
+ )
707
+ if continue_to_dev:
708
+ await _continue_into_dev_interview(
709
+ seed_path,
710
+ debug=debug,
711
+ llm_backend=backend,
712
+ )
670
713
  else:
671
714
  print_error(f"Failed to generate PM: {seed_result.error}")
672
715
  elif state.rounds and not state.is_complete:
@@ -0,0 +1,209 @@
1
+ """Helpers for resolving interview initial context from text or files."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import yaml
8
+
9
+ from ouroboros.bigbang.pm_seed import PMSeed
10
+ from ouroboros.core.errors import ValidationError
11
+ from ouroboros.core.security import InputValidator
12
+ from ouroboros.core.types import Result
13
+
14
+ _PM_SEED_SUFFIXES = {".json", ".yaml", ".yml"}
15
+ _TEXT_CONTEXT_SUFFIXES = {".md", ".markdown", ".txt", ".rst"}
16
+ _MAX_PATH_CANDIDATE_LENGTH = 240
17
+
18
+
19
+ def _is_pm_seed_candidate(seed_path: Path, raw_data: object) -> bool:
20
+ """Return True when a file should be treated as a PM-seed artifact."""
21
+ if seed_path.stem.startswith("pm_seed_"):
22
+ return True
23
+ if isinstance(raw_data, dict):
24
+ pm_id = raw_data.get("pm_id")
25
+ if isinstance(pm_id, str) and pm_id.startswith("pm_seed_"):
26
+ return True
27
+ return False
28
+
29
+
30
+ def _validate_pm_seed_mapping(
31
+ raw_data: dict[object, object], seed_path: Path
32
+ ) -> Result[None, ValidationError]:
33
+ """Validate the minimum PM-seed contract before conversion."""
34
+ pm_id = raw_data.get("pm_id")
35
+ product_name = raw_data.get("product_name")
36
+ goal = raw_data.get("goal")
37
+
38
+ has_pm_seed_filename = seed_path.stem.startswith("pm_seed_")
39
+ has_pm_seed_id = isinstance(pm_id, str) and pm_id.startswith("pm_seed_")
40
+
41
+ if (
42
+ not isinstance(pm_id, str)
43
+ or (not pm_id.strip())
44
+ or (not has_pm_seed_id and not has_pm_seed_filename)
45
+ ):
46
+ return Result.err(
47
+ ValidationError(
48
+ "PM seed file must include a non-empty pm_id and either a 'pm_seed_' filename or pm_id",
49
+ field="initial_context",
50
+ value=str(seed_path),
51
+ )
52
+ )
53
+
54
+ if not isinstance(product_name, str) or not product_name.strip():
55
+ return Result.err(
56
+ ValidationError(
57
+ "PM seed file must include a non-empty product_name",
58
+ field="initial_context",
59
+ value=str(seed_path),
60
+ )
61
+ )
62
+
63
+ if not isinstance(goal, str) or not goal.strip():
64
+ return Result.err(
65
+ ValidationError(
66
+ "PM seed file must include a non-empty goal",
67
+ field="initial_context",
68
+ value=str(seed_path),
69
+ )
70
+ )
71
+
72
+ return Result.ok(None)
73
+
74
+
75
+ def _resolve_path_candidate(
76
+ context_candidate: str,
77
+ *,
78
+ cwd: str | Path | None = None,
79
+ ) -> Path | None:
80
+ """Return a plausible file-path candidate, or None for literal text."""
81
+ if "\n" in context_candidate or len(context_candidate) > _MAX_PATH_CANDIDATE_LENGTH:
82
+ return None
83
+
84
+ try:
85
+ candidate_path = Path(context_candidate).expanduser()
86
+ except (OSError, ValueError):
87
+ return None
88
+
89
+ if not candidate_path.is_absolute() and cwd is not None:
90
+ candidate_path = Path(cwd).expanduser() / candidate_path
91
+
92
+ try:
93
+ if candidate_path.exists() and candidate_path.is_file():
94
+ return candidate_path
95
+ except OSError:
96
+ return None
97
+
98
+ return None
99
+
100
+
101
+ def load_pm_seed_as_context(seed_path: Path) -> Result[str, ValidationError]:
102
+ """Load a PMSeed artifact and convert it into dev-interview context."""
103
+ try:
104
+ raw_data = yaml.safe_load(seed_path.read_text(encoding="utf-8"))
105
+ except (OSError, yaml.YAMLError) as exc:
106
+ return Result.err(
107
+ ValidationError(
108
+ f"Failed to load PM seed: {exc}",
109
+ field="initial_context",
110
+ value=str(seed_path),
111
+ )
112
+ )
113
+
114
+ if not isinstance(raw_data, dict):
115
+ return Result.err(
116
+ ValidationError(
117
+ "PM seed file must contain an object mapping",
118
+ field="initial_context",
119
+ value=str(seed_path),
120
+ )
121
+ )
122
+
123
+ validation_result = _validate_pm_seed_mapping(raw_data, seed_path)
124
+ if validation_result.is_err:
125
+ return validation_result
126
+
127
+ pm_seed = PMSeed.from_dict(raw_data)
128
+ context = pm_seed.to_initial_context()
129
+ is_valid, error_message = InputValidator.validate_initial_context(context)
130
+ if not is_valid:
131
+ return Result.err(
132
+ ValidationError(
133
+ error_message,
134
+ field="initial_context",
135
+ value=str(seed_path),
136
+ )
137
+ )
138
+
139
+ return Result.ok(context)
140
+
141
+
142
+ def resolve_initial_context_input(
143
+ initial_context: str,
144
+ *,
145
+ cwd: str | Path | None = None,
146
+ ) -> Result[str, ValidationError]:
147
+ """Resolve interview input from literal text or an existing file path."""
148
+ context_candidate = initial_context.strip()
149
+ if not context_candidate:
150
+ return Result.err(
151
+ ValidationError(
152
+ "Initial context cannot be empty",
153
+ field="initial_context",
154
+ value=initial_context,
155
+ )
156
+ )
157
+
158
+ candidate_path = _resolve_path_candidate(context_candidate, cwd=cwd)
159
+ if candidate_path is not None:
160
+ suffix = candidate_path.suffix.lower()
161
+ if suffix in _PM_SEED_SUFFIXES:
162
+ try:
163
+ raw_data = yaml.safe_load(candidate_path.read_text(encoding="utf-8"))
164
+ except (OSError, yaml.YAMLError) as exc:
165
+ return Result.err(
166
+ ValidationError(
167
+ f"Failed to read initial context file: {exc}",
168
+ field="initial_context",
169
+ value=str(candidate_path),
170
+ )
171
+ )
172
+
173
+ if _is_pm_seed_candidate(candidate_path, raw_data):
174
+ return load_pm_seed_as_context(candidate_path)
175
+
176
+ if suffix in _TEXT_CONTEXT_SUFFIXES or suffix in _PM_SEED_SUFFIXES:
177
+ try:
178
+ file_context = candidate_path.read_text(encoding="utf-8")
179
+ except OSError as exc:
180
+ return Result.err(
181
+ ValidationError(
182
+ f"Failed to read initial context file: {exc}",
183
+ field="initial_context",
184
+ value=str(candidate_path),
185
+ )
186
+ )
187
+
188
+ is_valid, error_message = InputValidator.validate_initial_context(file_context)
189
+ if not is_valid:
190
+ return Result.err(
191
+ ValidationError(
192
+ error_message,
193
+ field="initial_context",
194
+ value=str(candidate_path),
195
+ )
196
+ )
197
+ return Result.ok(file_context)
198
+
199
+ is_valid, error_message = InputValidator.validate_initial_context(initial_context)
200
+ if not is_valid:
201
+ return Result.err(
202
+ ValidationError(
203
+ error_message,
204
+ field="initial_context",
205
+ value=initial_context,
206
+ )
207
+ )
208
+
209
+ return Result.ok(initial_context)
@@ -30,6 +30,7 @@ from ouroboros.bigbang.interview import (
30
30
  from ouroboros.bigbang.seed_generator import SeedGenerator
31
31
  from ouroboros.config import get_clarification_model
32
32
  from ouroboros.core.errors import ValidationError
33
+ from ouroboros.core.initial_context import resolve_initial_context_input
33
34
  from ouroboros.core.types import Result
34
35
  from ouroboros.mcp.errors import MCPServerError, MCPToolError
35
36
  from ouroboros.mcp.types import (
@@ -678,7 +679,16 @@ class InterviewHandler:
678
679
  # Start new interview
679
680
  if initial_context:
680
681
  cwd = arguments.get("cwd") or os.getcwd()
681
- result = await engine.start_interview(initial_context, cwd=cwd)
682
+ resolved_context = resolve_initial_context_input(initial_context, cwd=cwd)
683
+ if resolved_context.is_err:
684
+ return Result.err(
685
+ MCPToolError(
686
+ str(resolved_context.error),
687
+ tool_name="ouroboros_interview",
688
+ )
689
+ )
690
+
691
+ result = await engine.start_interview(resolved_context.value, cwd=cwd)
682
692
  if result.is_err:
683
693
  return Result.err(
684
694
  MCPToolError(
@@ -762,7 +772,7 @@ class InterviewHandler:
762
772
  await self._emit_event(
763
773
  interview_started(
764
774
  state.interview_id,
765
- initial_context,
775
+ resolved_context.value,
766
776
  )
767
777
  )
768
778
 
@@ -48,6 +48,7 @@ from ouroboros.mcp.types import (
48
48
  ToolInputType,
49
49
  )
50
50
  from ouroboros.persistence.brownfield import BrownfieldRepo, BrownfieldStore
51
+ from ouroboros.pm.handoff import build_pm_dev_handoff_next_step
51
52
  from ouroboros.providers import create_llm_adapter
52
53
 
53
54
  log = structlog.get_logger()
@@ -1230,6 +1231,7 @@ class PMInterviewHandler:
1230
1231
 
1231
1232
  seed = seed_result.value
1232
1233
 
1234
+ # Save seed to ~/.ouroboros/seeds/ (idempotent — overwrites on retry)
1233
1235
  # Save seed and PM document with recovery contract
1234
1236
  try:
1235
1237
  seed_path = engine.save_pm_seed(seed)
@@ -1258,6 +1260,8 @@ class PMInterviewHandler:
1258
1260
  )
1259
1261
  )
1260
1262
 
1263
+ next_step = build_pm_dev_handoff_next_step(seed_path)
1264
+
1261
1265
  return Result.ok(
1262
1266
  MCPToolResult(
1263
1267
  content=(
@@ -1265,10 +1269,13 @@ class PMInterviewHandler:
1265
1269
  type=ContentType.TEXT,
1266
1270
  text=(
1267
1271
  f"PM seed generated: {seed.product_name}\n"
1268
- f"Seed: {seed_path}\n"
1272
+ f"PM seed: {seed_path}\n"
1269
1273
  f"PM document: {pm_path}\n\n"
1274
+ "This PM seed is a handoff artifact for the dev interview, "
1275
+ "not the runnable Seed.\n"
1270
1276
  f"Deferred items: {len(seed.deferred_items)}\n"
1271
- f"Decide-later items: {len(seed.decide_later_items)}"
1277
+ f"Decide-later items: {len(seed.decide_later_items)}\n"
1278
+ f"Next: {next_step}"
1272
1279
  ),
1273
1280
  ),
1274
1281
  ),
@@ -1276,8 +1283,11 @@ class PMInterviewHandler:
1276
1283
  meta={
1277
1284
  "session_id": session_id,
1278
1285
  "seed_path": str(seed_path),
1286
+ "pm_seed_path": str(seed_path),
1279
1287
  "pm_path": str(pm_path),
1280
- "next_step": f"Run 'ooo interview' to start a dev interview using {pm_path} as context",
1288
+ "artifact_kind": "pm_seed",
1289
+ "runnable": False,
1290
+ "next_step": next_step,
1281
1291
  },
1282
1292
  )
1283
1293
  )
@@ -0,0 +1,18 @@
1
+ """Shared PM handoff messaging helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+
8
+ def build_pm_dev_handoff_command(seed_path: Path | str) -> str:
9
+ """Return the canonical command for continuing from a PM seed."""
10
+ return f"ouroboros init start {seed_path}"
11
+
12
+
13
+ def build_pm_dev_handoff_next_step(seed_path: Path | str) -> str:
14
+ """Return the canonical PM-to-dev handoff message."""
15
+ return (
16
+ f"Run '{build_pm_dev_handoff_command(seed_path)}' to continue into the dev interview. "
17
+ "The runnable Seed is generated after that dev interview completes."
18
+ )
@@ -89,9 +89,11 @@ class ClaudeCodeAdapter:
89
89
  self,
90
90
  permission_mode: str = "default",
91
91
  cli_path: str | Path | None = None,
92
+ cwd: str | Path | None = None,
92
93
  allowed_tools: list[str] | None = None,
93
94
  max_turns: int = 1,
94
95
  on_message: Callable[[str, str], None] | None = None,
96
+ timeout: float | None = None,
95
97
  ) -> None:
96
98
  """Initialize Claude Code adapter.
97
99
 
@@ -102,23 +104,34 @@ class ClaudeCodeAdapter:
102
104
  cli_path: Path to the Claude CLI binary. If not provided,
103
105
  checks OUROBOROS_CLI_PATH env var, then falls back to
104
106
  SDK's bundled CLI.
105
- allowed_tools: List of tools to allow. None means no tools.
106
- For interview mode with codebase access, use ["Read", "Glob", "Grep"].
107
+ cwd: Working directory passed to the Claude Agent SDK.
108
+ allowed_tools: Explicit allow-list for Claude tools. ``None`` keeps
109
+ the default permissive mode while still blocking dangerous tools.
110
+ Use ``[]`` to forbid all Claude tools.
107
111
  max_turns: Maximum turns for the conversation. Default 1 for
108
112
  single-response completions (most MCP use cases).
109
113
  on_message: Callback for streaming messages. Called with (type, content):
110
114
  - ("thinking", "content") for agent reasoning
111
115
  - ("tool", "tool_name") for tool usage
116
+ timeout: Optional application-level timeout in seconds for a
117
+ single completion request. When set, aborts before outer
118
+ transport timeouts and returns a ProviderError.
112
119
  """
113
120
  self._permission_mode: str = permission_mode
114
121
  self._cli_path: Path | None = self._resolve_cli_path(cli_path)
115
- self._allowed_tools: list[str] = allowed_tools or []
122
+ self._cwd: str = str(Path(cwd).expanduser()) if cwd is not None else os.getcwd()
123
+ self._allowed_tools: list[str] | None = (
124
+ list(allowed_tools) if allowed_tools is not None else None
125
+ )
116
126
  self._max_turns: int = max_turns
117
127
  self._on_message: Callable[[str, str], None] | None = on_message
128
+ self._timeout: float | None = timeout if timeout and timeout > 0 else None
118
129
  log.info(
119
130
  "claude_code_adapter.initialized",
120
131
  permission_mode=permission_mode,
121
132
  cli_path=str(self._cli_path) if self._cli_path else None,
133
+ cwd=self._cwd,
134
+ timeout_seconds=self._timeout,
122
135
  )
123
136
 
124
137
  def _resolve_cli_path(self, cli_path: str | Path | None) -> Path | None:
@@ -260,9 +273,15 @@ class ClaudeCodeAdapter:
260
273
 
261
274
  for attempt in range(_MAX_RETRIES):
262
275
  try:
263
- result = await self._execute_single_request(
264
- prompt, config, system_prompt=system_prompt
265
- )
276
+ if self._timeout is None:
277
+ result = await self._execute_single_request(
278
+ prompt, config, system_prompt=system_prompt
279
+ )
280
+ else:
281
+ async with asyncio.timeout(self._timeout):
282
+ result = await self._execute_single_request(
283
+ prompt, config, system_prompt=system_prompt
284
+ )
266
285
 
267
286
  if result.is_ok:
268
287
  if attempt > 0:
@@ -290,6 +309,22 @@ class ClaudeCodeAdapter:
290
309
  # Non-retryable error
291
310
  return result
292
311
 
312
+ except TimeoutError:
313
+ log.warning(
314
+ "claude_code_adapter.request_timed_out",
315
+ timeout_seconds=self._timeout,
316
+ attempt=attempt + 1,
317
+ )
318
+ return Result.err(
319
+ ProviderError(
320
+ message=f"Claude Code request timed out after {self._timeout:.1f}s",
321
+ details={
322
+ "timed_out": True,
323
+ "timeout_seconds": self._timeout,
324
+ "attempt": attempt + 1,
325
+ },
326
+ )
327
+ )
293
328
  except Exception as e:
294
329
  error_str = str(e)
295
330
  error_type = type(e).__name__
@@ -405,16 +440,17 @@ class ClaudeCodeAdapter:
405
440
  log.debug("claude_code_adapter.stderr", line=line[:200])
406
441
 
407
442
  options_kwargs: dict = {
408
- "allowed_tools": self._allowed_tools if self._allowed_tools is not None else [],
409
443
  "disallowed_tools": disallowed,
410
444
  "max_turns": self._max_turns,
411
445
  # Allow MCP and other ~/.claude/ settings to be inherited
412
446
  "permission_mode": self._permission_mode,
413
- "cwd": os.getcwd(),
447
+ "cwd": self._cwd,
414
448
  "cli_path": self._cli_path,
415
449
  "stderr": _stderr_callback,
416
450
  "env": env_overrides,
417
451
  }
452
+ if self._allowed_tools is not None:
453
+ options_kwargs["allowed_tools"] = self._allowed_tools
418
454
 
419
455
  # Pass model from CompletionConfig if specified
420
456
  # "default" is not a valid SDK model — treat it as None (use SDK default)
@@ -81,7 +81,7 @@ class CodexCliLLMAdapter:
81
81
  self._cli_path = self._resolve_cli_path(cli_path)
82
82
  self._cwd = str(Path(cwd).expanduser()) if cwd is not None else os.getcwd()
83
83
  self._permission_mode = self._resolve_permission_mode(permission_mode)
84
- self._allowed_tools = allowed_tools or []
84
+ self._allowed_tools = list(allowed_tools) if allowed_tools is not None else None
85
85
  self._max_turns = max_turns
86
86
  self._on_message = on_message
87
87
  self._max_retries = max_retries
@@ -150,12 +150,22 @@ class CodexCliLLMAdapter:
150
150
  "If you need tools, prefer using only the following tools:\n"
151
151
  + "\n".join(f"- {tool}" for tool in self._allowed_tools)
152
152
  )
153
+ elif self._allowed_tools is not None:
154
+ # Explicit empty list means no tools allowed — text-only response
155
+ parts.append("## Tool Constraints")
156
+ parts.append("Do NOT use any tools or MCP calls. Respond with plain text only.")
153
157
 
154
158
  if self._max_turns > 0:
155
159
  parts.append("## Execution Budget")
156
- parts.append(
157
- f"Keep the work within at most {self._max_turns} tool-assisted turns if possible."
158
- )
160
+ if self._allowed_tools == []:
161
+ parts.append(
162
+ "Answer directly in plain text and avoid turning this into a "
163
+ "multi-step tool workflow."
164
+ )
165
+ else:
166
+ parts.append(
167
+ f"Keep the work within at most {self._max_turns} tool-assisted turns if possible."
168
+ )
159
169
 
160
170
  for message in messages:
161
171
  if message.role == MessageRole.SYSTEM:
@@ -94,9 +94,11 @@ def create_llm_adapter(
94
94
  return ClaudeCodeAdapter(
95
95
  permission_mode=resolved_permission_mode,
96
96
  cli_path=cli_path,
97
+ cwd=cwd,
97
98
  allowed_tools=allowed_tools,
98
99
  max_turns=max_turns,
99
100
  on_message=on_message,
101
+ timeout=timeout,
100
102
  )
101
103
  if resolved_backend == "codex":
102
104
  return CodexCliLLMAdapter(
@@ -110,7 +112,14 @@ def create_llm_adapter(
110
112
  max_retries=max_retries,
111
113
  )
112
114
  # opencode is rejected at resolve time; this is a defensive fallback
113
- from ouroboros.providers.litellm_adapter import LiteLLMAdapter
115
+ try:
116
+ from ouroboros.providers.litellm_adapter import LiteLLMAdapter
117
+ except ImportError as exc:
118
+ msg = (
119
+ "litellm backend requested but litellm is not installed. "
120
+ "Install with: pip install 'ouroboros-ai[litellm]'"
121
+ )
122
+ raise RuntimeError(msg) from exc
114
123
 
115
124
  return LiteLLMAdapter(
116
125
  api_key=api_key,
@@ -16,6 +16,7 @@ from ouroboros.cli.commands.init import (
16
16
  _load_pm_seed_as_context,
17
17
  _notify_pm_seed_detected,
18
18
  _prompt_pm_seed_selection,
19
+ start,
19
20
  )
20
21
 
21
22
  # ---------------------------------------------------------------------------
@@ -550,3 +551,36 @@ class TestPrdSeedConfirmationFlow:
550
551
  assert parsed["goal"] == "End-to-end testing"
551
552
  assert "Analytics" in parsed["deferred_items"]
552
553
  assert "Hosting provider" in parsed["decide_later_items"]
554
+
555
+
556
+ class TestStartCommandPathResolution:
557
+ """Tests for starting the dev interview from a PM artifact path."""
558
+
559
+ def test_start_resolves_pm_seed_path_before_running_interview(self, tmp_path: Path) -> None:
560
+ seed_path = tmp_path / "pm_seed_taskflow.json"
561
+ seed_path.write_text(
562
+ """{
563
+ "pm_id": "pm_seed_taskflow",
564
+ "product_name": "TaskFlow",
565
+ "goal": "Help teams manage tasks",
566
+ "constraints": ["Offline support"],
567
+ "success_criteria": ["Tasks sync correctly"],
568
+ "user_stories": [],
569
+ "deferred_items": [],
570
+ "decide_later_items": []
571
+ }
572
+ """,
573
+ encoding="utf-8",
574
+ )
575
+
576
+ with (
577
+ patch.object(Path, "home", return_value=tmp_path),
578
+ patch("ouroboros.cli.commands.init.asyncio.run"),
579
+ patch("ouroboros.cli.commands.init._run_interview") as mock_run_interview,
580
+ patch("ouroboros.cli.commands.init.print_info"),
581
+ ):
582
+ start(context=str(seed_path), resume=None)
583
+
584
+ resolved_context = mock_run_interview.call_args.args[0]
585
+ assert "TaskFlow" in resolved_context
586
+ assert str(seed_path) not in resolved_context