ouroboros-ai 0.26.5.dev2__tar.gz → 0.26.5.dev4__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 (569) hide show
  1. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/PKG-INFO +1 -1
  2. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/pm/SKILL.md +27 -15
  3. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/_version.py +2 -2
  4. ouroboros_ai-0.26.5.dev4/src/ouroboros/bigbang/pm_completion.py +61 -0
  5. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/pm_interview.py +98 -45
  6. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/question_classifier.py +24 -12
  7. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/pm.py +97 -4
  8. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/pm_handler.py +252 -50
  9. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_decide_later_items.py +155 -106
  10. ouroboros_ai-0.26.5.dev4/tests/unit/bigbang/test_pm_completion.py +76 -0
  11. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_pm_interview.py +52 -145
  12. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_question_classifier.py +7 -7
  13. ouroboros_ai-0.26.5.dev4/tests/unit/cli/test_pm_completion.py +117 -0
  14. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_pm_interactive_logging.py +13 -0
  15. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_pm_handler.py +293 -24
  16. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.claude/settings.json +0 -0
  17. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.claude-plugin/.mcp.json +0 -0
  18. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.claude-plugin/marketplace.json +0 -0
  19. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.claude-plugin/plugin.json +0 -0
  20. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.env.example +0 -0
  21. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  22. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  23. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  24. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  25. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/workflows/dev-publish.yml +0 -0
  26. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/workflows/lint.yml +0 -0
  27. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/workflows/release.yml +0 -0
  28. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.github/workflows/test.yml +0 -0
  29. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.gitignore +0 -0
  30. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.mcp.json +0 -0
  31. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.ouroboros/mechanical.toml +0 -0
  32. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.pre-commit-config.yaml +0 -0
  33. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/.python-version +0 -0
  34. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/CHANGELOG.md +0 -0
  35. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/CLAUDE.md +0 -0
  36. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/CODE_OF_CONDUCT.md +0 -0
  37. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/CONTRIBUTING.md +0 -0
  38. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/HANDOFF.md +0 -0
  39. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/LICENSE +0 -0
  40. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/README.ko.md +0 -0
  41. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/README.md +0 -0
  42. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/SECURITY.md +0 -0
  43. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/UNINSTALL.md +0 -0
  44. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/cancel.md +0 -0
  45. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/evaluate.md +0 -0
  46. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/evolve.md +0 -0
  47. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/help.md +0 -0
  48. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/interview.md +0 -0
  49. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/ralph.md +0 -0
  50. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/run.md +0 -0
  51. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/seed.md +0 -0
  52. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/setup.md +0 -0
  53. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/status.md +0 -0
  54. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/tutorial.md +0 -0
  55. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/unstuck.md +0 -0
  56. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/commands/welcome.md +0 -0
  57. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/.gitignore +0 -0
  58. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/Cargo.lock +0 -0
  59. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/Cargo.toml +0 -0
  60. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/README.md +0 -0
  61. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/db.rs +0 -0
  62. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/main.rs +0 -0
  63. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/mock.rs +0 -0
  64. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/state.rs +0 -0
  65. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
  66. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/views/execution.rs +0 -0
  67. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
  68. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/views/logs.rs +0 -0
  69. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/views/mod.rs +0 -0
  70. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
  71. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/README.md +0 -0
  72. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/api/README.md +0 -0
  73. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/api/core.md +0 -0
  74. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/api/mcp.md +0 -0
  75. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/architecture.md +0 -0
  76. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/cli-reference.md +0 -0
  77. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/config-reference.md +0 -0
  78. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/contributing/architecture-overview.md +0 -0
  79. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/contributing/findings-registry.md +0 -0
  80. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/contributing/issue-quality-policy.md +0 -0
  81. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/contributing/key-patterns.md +0 -0
  82. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/contributing/testing-guide.md +0 -0
  83. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/examples/mcp-config.yaml +0 -0
  84. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/getting-started.md +0 -0
  85. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/guides/evaluation-pipeline.md +0 -0
  86. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/guides/evolution-loop.md +0 -0
  87. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
  88. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/guides/seed-authoring.md +0 -0
  89. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/guides/tui-usage.md +0 -0
  90. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/images/PLACEHOLDER_README.md +0 -0
  91. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/images/ouroboros.png +0 -0
  92. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/platform-support.md +0 -0
  93. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/runtime-capability-matrix.md +0 -0
  94. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/runtime-guides/claude-code.md +0 -0
  95. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/docs/runtime-guides/codex.md +0 -0
  96. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/coordinator_test_seed.yaml +0 -0
  97. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/dummy_seed.yaml +0 -0
  98. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/parallel_subac_test_seed.yaml +0 -0
  99. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/subac_test_seed.yaml +0 -0
  100. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/task_manager/README.md +0 -0
  101. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/task_manager/__init__.py +0 -0
  102. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/task_manager/__main__.py +0 -0
  103. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/task_manager/cli.py +0 -0
  104. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/task_manager/models.py +0 -0
  105. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/task_manager/storage.py +0 -0
  106. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/examples/test_display.py +0 -0
  107. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/hooks/hooks.json +0 -0
  108. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/llms-full.txt +0 -0
  109. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/llms.txt +0 -0
  110. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/project-context.md +0 -0
  111. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/pyproject.toml +0 -0
  112. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/drift-monitor.py +0 -0
  113. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/install.sh +0 -0
  114. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/keyword-detector.py +0 -0
  115. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/mcp-serve.sh +0 -0
  116. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/ralph-rewind.py +0 -0
  117. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/ralph.py +0 -0
  118. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/ralph.sh +0 -0
  119. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/session-start.py +0 -0
  120. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/sync-plugin-version.py +0 -0
  121. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/scripts/version-check.py +0 -0
  122. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/brownfield/SKILL.md +0 -0
  123. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/cancel/SKILL.md +0 -0
  124. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/evaluate/SKILL.md +0 -0
  125. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/evolve/SKILL.md +0 -0
  126. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/help/SKILL.md +0 -0
  127. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/interview/SKILL.md +0 -0
  128. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/qa/SKILL.md +0 -0
  129. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/ralph/SKILL.md +0 -0
  130. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/run/SKILL.md +0 -0
  131. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/seed/SKILL.md +0 -0
  132. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/setup/SKILL.md +0 -0
  133. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/status/SKILL.md +0 -0
  134. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/tutorial/SKILL.md +0 -0
  135. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/unstuck/SKILL.md +0 -0
  136. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/update/SKILL.md +0 -0
  137. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/skills/welcome/SKILL.md +0 -0
  138. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/__init__.py +0 -0
  139. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/__main__.py +0 -0
  140. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/__init__.py +0 -0
  141. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/advocate.md +0 -0
  142. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/analysis-agent.md +0 -0
  143. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/architect.md +0 -0
  144. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/breadth-keeper.md +0 -0
  145. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/code-executor.md +0 -0
  146. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/codebase-explorer.md +0 -0
  147. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/consensus-reviewer.md +0 -0
  148. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/contrarian.md +0 -0
  149. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/evaluator.md +0 -0
  150. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/hacker.md +0 -0
  151. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/judge.md +0 -0
  152. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/loader.py +0 -0
  153. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/ontologist.md +0 -0
  154. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/ontology-analyst.md +0 -0
  155. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/qa-judge.md +0 -0
  156. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/research-agent.md +0 -0
  157. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/researcher.md +0 -0
  158. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/seed-architect.md +0 -0
  159. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/seed-closer.md +0 -0
  160. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/semantic-evaluator.md +0 -0
  161. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/simplifier.md +0 -0
  162. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/agents/socratic-interviewer.md +0 -0
  163. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/__init__.py +0 -0
  164. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/ambiguity.py +0 -0
  165. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/brownfield.py +0 -0
  166. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/explore.py +0 -0
  167. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/interview.py +0 -0
  168. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/pm_document.py +0 -0
  169. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/pm_seed.py +0 -0
  170. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/bigbang/seed_generator.py +0 -0
  171. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/__init__.py +0 -0
  172. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/__init__.py +0 -0
  173. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/cancel.py +0 -0
  174. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/config.py +0 -0
  175. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/init.py +0 -0
  176. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/mcp.py +0 -0
  177. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/run.py +0 -0
  178. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/setup.py +0 -0
  179. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/status.py +0 -0
  180. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/tui.py +0 -0
  181. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/commands/uninstall.py +0 -0
  182. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/formatters/__init__.py +0 -0
  183. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/formatters/panels.py +0 -0
  184. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/formatters/progress.py +0 -0
  185. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/formatters/prompting.py +0 -0
  186. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/formatters/tables.py +0 -0
  187. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
  188. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/cli/main.py +0 -0
  189. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/codex/__init__.py +0 -0
  190. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/codex/artifacts.py +0 -0
  191. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/codex/ouroboros.md +0 -0
  192. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/codex_permissions.py +0 -0
  193. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/config/__init__.py +0 -0
  194. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/config/loader.py +0 -0
  195. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/config/models.py +0 -0
  196. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/__init__.py +0 -0
  197. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/ac_tree.py +0 -0
  198. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/context.py +0 -0
  199. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/errors.py +0 -0
  200. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/file_lock.py +0 -0
  201. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/git_workflow.py +0 -0
  202. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/lineage.py +0 -0
  203. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/ontology_aspect.py +0 -0
  204. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/ontology_questions.py +0 -0
  205. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/project_paths.py +0 -0
  206. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/security.py +0 -0
  207. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/seed.py +0 -0
  208. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/text.py +0 -0
  209. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/types.py +0 -0
  210. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/core/worktree.py +0 -0
  211. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/__init__.py +0 -0
  212. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/artifact_collector.py +0 -0
  213. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/consensus.py +0 -0
  214. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/json_utils.py +0 -0
  215. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/languages.py +0 -0
  216. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/mechanical.py +0 -0
  217. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/models.py +0 -0
  218. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/pipeline.py +0 -0
  219. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/semantic.py +0 -0
  220. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/trigger.py +0 -0
  221. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
  222. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/__init__.py +0 -0
  223. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/base.py +0 -0
  224. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/decomposition.py +0 -0
  225. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/evaluation.py +0 -0
  226. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/interview.py +0 -0
  227. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/lineage.py +0 -0
  228. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/events/ontology.py +0 -0
  229. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/__init__.py +0 -0
  230. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/convergence.py +0 -0
  231. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/loop.py +0 -0
  232. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/projector.py +0 -0
  233. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/reflect.py +0 -0
  234. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/regression.py +0 -0
  235. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/evolution/wonder.py +0 -0
  236. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/execution/__init__.py +0 -0
  237. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/execution/atomicity.py +0 -0
  238. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/execution/decomposition.py +0 -0
  239. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/execution/double_diamond.py +0 -0
  240. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/execution/subagent.py +0 -0
  241. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/__init__.py +0 -0
  242. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/client/__init__.py +0 -0
  243. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/client/adapter.py +0 -0
  244. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/client/manager.py +0 -0
  245. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/client/protocol.py +0 -0
  246. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/errors.py +0 -0
  247. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/job_manager.py +0 -0
  248. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/resources/__init__.py +0 -0
  249. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/resources/handlers.py +0 -0
  250. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/server/__init__.py +0 -0
  251. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/server/adapter.py +0 -0
  252. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/server/protocol.py +0 -0
  253. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/server/security.py +0 -0
  254. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/__init__.py +0 -0
  255. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
  256. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
  257. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/dashboard.py +0 -0
  258. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/definitions.py +0 -0
  259. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
  260. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
  261. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
  262. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
  263. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/qa.py +0 -0
  264. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
  265. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/tools/registry.py +0 -0
  266. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/mcp/types.py +0 -0
  267. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/observability/__init__.py +0 -0
  268. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/observability/drift.py +0 -0
  269. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/observability/logging.py +0 -0
  270. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/observability/retrospective.py +0 -0
  271. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/__init__.py +0 -0
  272. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/adapter.py +0 -0
  273. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
  274. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
  275. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/coordinator.py +0 -0
  276. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
  277. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/events.py +0 -0
  278. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
  279. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
  280. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/heartbeat.py +0 -0
  281. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/level_context.py +0 -0
  282. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/mcp_config.py +0 -0
  283. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
  284. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
  285. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
  286. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/runner.py +0 -0
  287. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
  288. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
  289. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/session.py +0 -0
  290. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/orchestrator/workflow_state.py +0 -0
  291. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/__init__.py +0 -0
  292. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/brownfield.py +0 -0
  293. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/checkpoint.py +0 -0
  294. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/event_store.py +0 -0
  295. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/migrations/__init__.py +0 -0
  296. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/migrations/runner.py +0 -0
  297. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
  298. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
  299. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/schema.py +0 -0
  300. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/persistence/uow.py +0 -0
  301. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/__init__.py +0 -0
  302. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/agents/__init__.py +0 -0
  303. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/agents/pool.py +0 -0
  304. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/agents/registry.py +0 -0
  305. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
  306. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/orchestration/router.py +0 -0
  307. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
  308. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/skills/__init__.py +0 -0
  309. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/skills/docs.py +0 -0
  310. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/skills/executor.py +0 -0
  311. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/skills/keywords.py +0 -0
  312. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/plugin/skills/registry.py +0 -0
  313. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/pm/__init__.py +0 -0
  314. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/pm/renderer.py +0 -0
  315. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/__init__.py +0 -0
  316. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/anthropic_adapter.py +0 -0
  317. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/base.py +0 -0
  318. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/claude_code_adapter.py +0 -0
  319. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/codex_cli_adapter.py +0 -0
  320. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/codex_cli_stream.py +0 -0
  321. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/factory.py +0 -0
  322. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/providers/litellm_adapter.py +0 -0
  323. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/py.typed +0 -0
  324. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/resilience/__init__.py +0 -0
  325. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/resilience/lateral.py +0 -0
  326. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/resilience/stagnation.py +0 -0
  327. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/routing/__init__.py +0 -0
  328. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/routing/complexity.py +0 -0
  329. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/routing/downgrade.py +0 -0
  330. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/routing/escalation.py +0 -0
  331. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/routing/router.py +0 -0
  332. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/routing/tiers.py +0 -0
  333. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/secondary/__init__.py +0 -0
  334. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/secondary/scheduler.py +0 -0
  335. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/secondary/todo_registry.py +0 -0
  336. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/strategies/__init__.py +0 -0
  337. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/strategies/devil_advocate.py +0 -0
  338. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/__init__.py +0 -0
  339. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/app.py +0 -0
  340. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/components/__init__.py +0 -0
  341. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/components/agents_panel.py +0 -0
  342. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/components/event_log.py +0 -0
  343. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/components/progress.py +0 -0
  344. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/components/token_tracker.py +0 -0
  345. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/events.py +0 -0
  346. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/__init__.py +0 -0
  347. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
  348. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/dashboard.py +0 -0
  349. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
  350. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
  351. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/debug.py +0 -0
  352. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/execution.py +0 -0
  353. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
  354. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
  355. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
  356. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/logs.py +0 -0
  357. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/screens/session_selector.py +0 -0
  358. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/__init__.py +0 -0
  359. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
  360. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
  361. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
  362. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
  363. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
  364. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
  365. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
  366. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
  367. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/verification/__init__.py +0 -0
  368. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/verification/extractor.py +0 -0
  369. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/verification/models.py +0 -0
  370. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/src/ouroboros/verification/verifier.py +0 -0
  371. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/__init__.py +0 -0
  372. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/conftest.py +0 -0
  373. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/e2e/__init__.py +0 -0
  374. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/e2e/conftest.py +0 -0
  375. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/e2e/test_cli_commands.py +0 -0
  376. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/e2e/test_full_workflow.py +0 -0
  377. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/e2e/test_session_persistence.py +0 -0
  378. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/fixtures/test_atomicity_seed.yml +0 -0
  379. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/__init__.py +0 -0
  380. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/conftest.py +0 -0
  381. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/mcp/__init__.py +0 -0
  382. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/mcp/conftest.py +0 -0
  383. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/mcp/test_client_adapter.py +0 -0
  384. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/mcp/test_client_manager.py +0 -0
  385. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/mcp/test_server_adapter.py +0 -0
  386. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/plugin/test_orchestration.py +0 -0
  387. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
  388. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/test_codex_skill_fallback.py +0 -0
  389. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/test_codex_skill_smoke.py +0 -0
  390. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/integration/test_entry_point.py +0 -0
  391. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/__init__.py +0 -0
  392. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/agents/__init__.py +0 -0
  393. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/agents/test_loader.py +0 -0
  394. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/__init__.py +0 -0
  395. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_ambiguity.py +0 -0
  396. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_brownfield.py +0 -0
  397. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_classifier_context.py +0 -0
  398. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_explore.py +0 -0
  399. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_interview.py +0 -0
  400. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
  401. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
  402. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
  403. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
  404. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
  405. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/bigbang/test_seed_generator.py +0 -0
  406. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/__init__.py +0 -0
  407. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/__init__.py +0 -0
  408. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/test_console.py +0 -0
  409. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/test_panels.py +0 -0
  410. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/test_progress.py +0 -0
  411. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/test_prompting.py +0 -0
  412. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/test_tables.py +0 -0
  413. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
  414. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_cancel.py +0 -0
  415. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_config.py +0 -0
  416. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_init_pm_seed_detection.py +0 -0
  417. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_init_runtime.py +0 -0
  418. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_main.py +0 -0
  419. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
  420. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
  421. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_pm.py +0 -0
  422. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_pm_brownfield.py +0 -0
  423. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
  424. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_pm_overwrite.py +0 -0
  425. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_pm_select_repos.py +0 -0
  426. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_run_qa.py +0 -0
  427. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_setup.py +0 -0
  428. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/cli/test_uninstall.py +0 -0
  429. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/config/__init__.py +0 -0
  430. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/config/test_loader.py +0 -0
  431. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/config/test_models.py +0 -0
  432. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/__init__.py +0 -0
  433. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_ac_tree.py +0 -0
  434. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_context.py +0 -0
  435. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_errors.py +0 -0
  436. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_git_workflow.py +0 -0
  437. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_lineage.py +0 -0
  438. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_ontology_aspect.py +0 -0
  439. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_ontology_questions.py +0 -0
  440. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_security.py +0 -0
  441. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_seed.py +0 -0
  442. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_types.py +0 -0
  443. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/core/test_worktree.py +0 -0
  444. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/__init__.py +0 -0
  445. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_consensus.py +0 -0
  446. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_json_utils.py +0 -0
  447. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_languages.py +0 -0
  448. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_mechanical.py +0 -0
  449. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_models.py +0 -0
  450. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_semantic.py +0 -0
  451. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_trigger.py +0 -0
  452. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
  453. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/events/__init__.py +0 -0
  454. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/events/test_base.py +0 -0
  455. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/events/test_decomposition_events.py +0 -0
  456. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/evolution/test_wonder_scope.py +0 -0
  457. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/execution/__init__.py +0 -0
  458. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/execution/test_atomicity.py +0 -0
  459. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/execution/test_decomposition.py +0 -0
  460. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/execution/test_double_diamond.py +0 -0
  461. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/execution/test_subagent_isolation.py +0 -0
  462. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/__init__.py +0 -0
  463. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/client/__init__.py +0 -0
  464. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/client/test_adapter.py +0 -0
  465. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/client/test_manager.py +0 -0
  466. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/conftest.py +0 -0
  467. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/server/__init__.py +0 -0
  468. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/server/test_adapter.py +0 -0
  469. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/server/test_security.py +0 -0
  470. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/test_errors.py +0 -0
  471. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/test_job_manager.py +0 -0
  472. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/test_types.py +0 -0
  473. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/__init__.py +0 -0
  474. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/conftest.py +0 -0
  475. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
  476. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_definitions.py +0 -0
  477. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_pm_handler_generate.py +0 -0
  478. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
  479. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
  480. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/mcp/tools/test_registry.py +0 -0
  481. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/observability/__init__.py +0 -0
  482. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/observability/test_drift.py +0 -0
  483. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/observability/test_logging.py +0 -0
  484. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/observability/test_retrospective.py +0 -0
  485. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/__init__.py +0 -0
  486. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_adapter.py +0 -0
  487. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
  488. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
  489. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
  490. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_coordinator.py +0 -0
  491. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
  492. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_events.py +0 -0
  493. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
  494. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
  495. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
  496. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_level_context.py +0 -0
  497. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_mcp_config.py +0 -0
  498. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
  499. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
  500. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
  501. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_runner.py +0 -0
  502. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
  503. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
  504. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
  505. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_session.py +0 -0
  506. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/orchestrator/test_workflow_state.py +0 -0
  507. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/persistence/__init__.py +0 -0
  508. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/persistence/test_brownfield_store.py +0 -0
  509. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/persistence/test_checkpoint.py +0 -0
  510. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/persistence/test_event_store.py +0 -0
  511. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/persistence/test_schema.py +0 -0
  512. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/persistence/test_uow.py +0 -0
  513. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/__init__.py +0 -0
  514. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/agents/__init__.py +0 -0
  515. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/agents/test_registry.py +0 -0
  516. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/orchestration/__init__.py +0 -0
  517. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
  518. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/skills/__init__.py +0 -0
  519. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/skills/test_keywords.py +0 -0
  520. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/plugin/skills/test_registry.py +0 -0
  521. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/pm/__init__.py +0 -0
  522. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/pm/test_renderer.py +0 -0
  523. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/providers/__init__.py +0 -0
  524. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/providers/test_base.py +0 -0
  525. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/providers/test_claude_code_adapter.py +0 -0
  526. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/providers/test_codex_cli_adapter.py +0 -0
  527. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/providers/test_factory.py +0 -0
  528. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/providers/test_litellm_adapter.py +0 -0
  529. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/resilience/__init__.py +0 -0
  530. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/resilience/test_lateral.py +0 -0
  531. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/resilience/test_stagnation.py +0 -0
  532. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/routing/__init__.py +0 -0
  533. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/routing/test_complexity.py +0 -0
  534. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/routing/test_downgrade.py +0 -0
  535. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/routing/test_escalation.py +0 -0
  536. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/routing/test_router.py +0 -0
  537. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/routing/test_tiers.py +0 -0
  538. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/scripts/test_keyword_detector.py +0 -0
  539. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/scripts/test_version_check.py +0 -0
  540. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/secondary/__init__.py +0 -0
  541. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/secondary/test_scheduler.py +0 -0
  542. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/secondary/test_todo_registry.py +0 -0
  543. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_artifact_collector.py +0 -0
  544. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_codex_artifacts.py +0 -0
  545. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_convergence.py +0 -0
  546. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_dashboard.py +0 -0
  547. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_dependencies_configured.py +0 -0
  548. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_evolve_rewind.py +0 -0
  549. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_evolve_step.py +0 -0
  550. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_graceful_shutdown.py +0 -0
  551. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_main_entry_point.py +0 -0
  552. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_module_structure.py +0 -0
  553. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_project_initialization.py +0 -0
  554. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_projector_rewind.py +0 -0
  555. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_ralph_parser.py +0 -0
  556. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_ralph_rewind.py +0 -0
  557. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_regression.py +0 -0
  558. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_tooling_configuration.py +0 -0
  559. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/test_verification.py +0 -0
  560. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/__init__.py +0 -0
  561. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_app.py +0 -0
  562. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_cancelled_display.py +0 -0
  563. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_events.py +0 -0
  564. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_lineage_viewer.py +0 -0
  565. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_screens.py +0 -0
  566. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_session_selector_replay.py +0 -0
  567. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tests/unit/tui/test_widgets.py +0 -0
  568. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/tools/sync_github_project.py +0 -0
  569. {ouroboros_ai-0.26.5.dev2 → ouroboros_ai-0.26.5.dev4}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ouroboros-ai
3
- Version: 0.26.5.dev2
3
+ Version: 0.26.5.dev4
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
@@ -66,41 +66,53 @@ Then check: does `meta.ask_user_question` exist?
66
66
  ```
67
67
  Do NOT modify it. Do NOT add options. Do NOT rephrase the question.
68
68
 
69
- - **NO** → This is an interview question. Use `AskUserQuestion` with `meta.question` and generate 2-3 suggested answers.
69
+ - **NO** → This is an interview question. Use `AskUserQuestion` with `meta.question`.
70
+ - If `meta.skip_eligible == true`: add a skip option based on `meta.classification`:
71
+ - `classification == "decide_later"` → add option `{"label": "Decide later", "description": "Skip — will be recorded as an open item in the PRD"}`
72
+ - `classification == "deferred"` → add option `{"label": "Defer to dev", "description": "Skip — this technical decision will be deferred to the development phase"}`
73
+ - Generate 2-3 suggested answers as the other options.
70
74
 
71
75
  **C. Relay answer back:**
72
76
 
77
+ If the user chose "Decide later" → send `answer="[decide_later]"`.
78
+ If the user chose "Defer to dev" → send `answer="[deferred]"`.
79
+ Otherwise → send the user's answer normally.
80
+
73
81
  ```
74
82
  Tool: ouroboros_pm_interview
75
83
  Arguments:
76
84
  session_id: <meta.session_id>
77
- <meta.response_param>: <user's answer>
85
+ <meta.response_param>: <user's answer or "[decide_later]" or "[deferred]">
78
86
  ```
79
87
 
80
88
  **D. Check completion:**
81
89
 
82
- If `meta.is_complete == true` → go to Step 4.
83
- Otherwise → repeat Step 3.
90
+ Completion is determined ONLY by `meta.is_complete` — NEVER by the response text.
91
+ The MCP response text may sound like the interview is wrapping up, but ignore it.
84
92
 
85
- ### Step 4: Generate
93
+ If `meta.is_complete == true`:
94
+ - If `meta.generation_failed == true` → retry generation:
95
+ ```
96
+ Tool: ouroboros_pm_interview
97
+ Arguments:
98
+ session_id: <session_id>
99
+ action: "generate"
100
+ cwd: <current working directory>
101
+ ```
102
+ - Otherwise → go to Step 4. The MCP auto-generated the PM document.
103
+ `meta.pm_path` and `meta.seed_path` contain the file paths.
86
104
 
87
- ```
88
- Tool: ouroboros_pm_interview
89
- Arguments:
90
- session_id: <session_id>
91
- action: "generate"
92
- cwd: <current working directory>
93
- ```
105
+ Otherwise → repeat Step 3, regardless of what the response text says.
94
106
 
95
- ### Step 5: Copy to Clipboard
107
+ ### Step 4: Copy to Clipboard
96
108
 
97
- After generation, read the pm.md file from `meta.pm_path` and copy its contents to the clipboard:
109
+ Read the pm.md file from `meta.pm_path` and copy its contents to the clipboard:
98
110
 
99
111
  ```bash
100
112
  cat <meta.pm_path> | pbcopy
101
113
  ```
102
114
 
103
- ### Step 6: Show Result & Next Step
115
+ ### Step 5: Show Result & Next Step
104
116
 
105
117
  Show the following to the user:
106
118
 
@@ -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.dev2'
22
- __version_tuple__ = version_tuple = (0, 26, 5, 'dev2')
21
+ __version__ = version = '0.26.5.dev4'
22
+ __version_tuple__ = version_tuple = (0, 26, 5, 'dev4')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,61 @@
1
+ """Shared PM interview completion helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from ouroboros.bigbang.interview import InterviewState
8
+ from ouroboros.bigbang.pm_interview import PMInterviewEngine
9
+ from ouroboros.core.errors import ValidationError
10
+ from ouroboros.core.types import Result
11
+
12
+
13
+ async def maybe_complete_pm_interview(
14
+ state: InterviewState,
15
+ engine: PMInterviewEngine,
16
+ ) -> Result[tuple[InterviewState, dict[str, Any] | None], ValidationError]:
17
+ """Run PM ambiguity completion logic and mark the interview complete if ready."""
18
+ completion = await engine.check_completion(state)
19
+ if completion is None:
20
+ return Result.ok((state, None))
21
+
22
+ complete_result = await engine.complete_interview(state)
23
+ if complete_result.is_err:
24
+ return Result.err(complete_result.error)
25
+
26
+ return Result.ok((complete_result.value, completion))
27
+
28
+
29
+ def build_pm_completion_summary(
30
+ *,
31
+ session_id: str,
32
+ completion: dict[str, Any] | None,
33
+ stored_ambiguity_score: float | None = None,
34
+ deferred_count: int,
35
+ decide_later_count: int,
36
+ decide_later_summary: str,
37
+ ) -> str:
38
+ """Build human-readable PM completion text for CLI and MCP flows."""
39
+ lines = [f"Interview complete. Session ID: {session_id}"]
40
+
41
+ if completion is not None:
42
+ lines.append(f"Rounds completed: {completion['rounds_completed']}")
43
+ lines.append(f"Completion reason: {completion['completion_reason']}")
44
+
45
+ ambiguity_score = (
46
+ completion.get("ambiguity_score") if completion is not None else stored_ambiguity_score
47
+ )
48
+ if ambiguity_score is not None:
49
+ lines.append(f"Ambiguity score: {ambiguity_score:.2f}")
50
+
51
+ lines.append("")
52
+ lines.append(f"Deferred items: {deferred_count}")
53
+ lines.append(f"Decide-later items: {decide_later_count}")
54
+
55
+ if decide_later_summary:
56
+ lines.append("")
57
+ lines.append(decide_later_summary)
58
+
59
+ lines.append("")
60
+ lines.append(f'Generate PM with: action="generate", session_id="{session_id}"')
61
+ return "\n".join(lines)
@@ -55,18 +55,7 @@ _SEED_DIR = Path.home() / ".ouroboros" / "seeds"
55
55
  _PM_SYSTEM_PROMPT_PREFIX = """\
56
56
  You are a Product Requirements interviewer helping a PM define their product.
57
57
 
58
- Focus on PRODUCT-LEVEL questions:
59
- - What problem does this solve and for whom?
60
- - What are the business goals and success metrics?
61
- - What are the user stories and workflows?
62
- - What constraints exist (timeline, budget, compliance)?
63
- - What is in scope vs out of scope?
64
- - What are the acceptance criteria?
65
-
66
- Do NOT ask about:
67
- - Implementation details (databases, frameworks, APIs)
68
- - Architecture decisions (microservices, deployment)
69
- - Code-level patterns or testing strategies
58
+ Focus on: goal, user stories, constraints, success criteria, assumptions.
70
59
 
71
60
  """
72
61
 
@@ -158,7 +147,8 @@ class PMInterviewEngine:
158
147
  """Original question text for questions classified as DECIDE_LATER.
159
148
 
160
149
  These are questions that are premature or unknowable at the PM stage.
161
- They are auto-answered with a placeholder and stored here so the PMSeed
150
+ The main session presents the question to the user with a "decide later"
151
+ option; when chosen, the caller records the item here so the PMSeed
162
152
  and PM document can surface them as explicit "decide later" decisions.
163
153
  """
164
154
  classifications: list[ClassificationResult] = field(default_factory=list)
@@ -484,47 +474,39 @@ class PMInterviewEngine:
484
474
  output_type = classification.output_type
485
475
 
486
476
  if output_type == ClassifierOutputType.DEFERRED:
487
- # Track as deferred item and generate a new question
488
- self.deferred_items.append(classification.original_question)
477
+ # Return the question to the caller (main session) so the user
478
+ # can choose to defer it themselves. The main session detects
479
+ # classification == "deferred" via response_meta and offers
480
+ # a "skip / defer to dev" option. If the user picks it, the
481
+ # caller calls skip_as_deferred() which records the deferral
482
+ # and appends to deferred_items.
483
+ #
484
+ # Previously this branch auto-answered and recursed, which could
485
+ # trigger MCP 120s timeouts on consecutive DEFERRED runs.
489
486
  log.info(
490
- "pm.question_deferred",
487
+ "pm.question_deferred_candidate",
491
488
  question=classification.original_question[:100],
492
489
  reasoning=classification.reasoning,
493
490
  output_type=output_type,
494
491
  )
495
- # Feed an automatic response back to the inner InterviewEngine
496
- # so the round is properly recorded and the engine advances.
497
- # This prevents the inner engine from re-generating similar
498
- # technical questions it doesn't know were already handled.
499
- await self.record_response(
500
- state,
501
- user_response="[Deferred to development phase] "
502
- "This technical decision will be addressed during the "
503
- "development interview.",
504
- question=classification.original_question,
505
- )
506
- # Recursively ask for the next real question
507
- return await self.ask_next_question(state)
492
+ return Result.ok(classification.original_question)
508
493
 
509
494
  if output_type == ClassifierOutputType.DECIDE_LATER:
510
- # Auto-answer with placeholder — no PM interaction needed
511
- placeholder = classification.placeholder_response
512
- self.decide_later_items.append(classification.original_question)
495
+ # Return the question to the caller (main session) so the user
496
+ # can choose "decide later" themselves. The main session detects
497
+ # classification == "decide_later" via response_meta and offers
498
+ # the option. If the user picks it, the caller calls
499
+ # skip_as_decide_later() which records the placeholder and
500
+ # appends to decide_later_items.
501
+ #
502
+ # Previously this branch auto-answered and recursed, which could
503
+ # trigger MCP 120s timeouts on consecutive DECIDE_LATER runs.
513
504
  log.info(
514
505
  "pm.question_decide_later",
515
506
  question=classification.original_question[:100],
516
- placeholder=placeholder[:100],
517
507
  reasoning=classification.reasoning,
518
508
  )
519
- # Record the placeholder as the response so the interview
520
- # engine advances its round count
521
- await self.record_response(
522
- state,
523
- user_response=f"[Decide later] {placeholder}",
524
- question=classification.original_question,
525
- )
526
- # Recursively ask for the next real question
527
- return await self.ask_next_question(state)
509
+ return Result.ok(classification.original_question)
528
510
 
529
511
  if output_type == ClassifierOutputType.REFRAMED:
530
512
  # Use the reframed version and track the mapping
@@ -595,6 +577,76 @@ class PMInterviewEngine:
595
577
 
596
578
  return await self.inner.record_response(state, user_response, question)
597
579
 
580
+ async def skip_as_decide_later(
581
+ self,
582
+ state: InterviewState,
583
+ question: str,
584
+ ) -> Result[InterviewState, ValidationError]:
585
+ """Skip a question as "decide later" at the user's explicit request.
586
+
587
+ Records the question in ``decide_later_items`` and feeds a placeholder
588
+ response to the inner InterviewEngine so the round is properly recorded
589
+ and the engine advances.
590
+
591
+ This is called when the main session detects that the user chose the
592
+ "decide later" option for a DECIDE_LATER-classified question, instead
593
+ of the old auto-skip behavior inside ``ask_next_question``.
594
+
595
+ Args:
596
+ state: Current interview state.
597
+ question: The question the user chose to decide later.
598
+
599
+ Returns:
600
+ Result containing updated state or ValidationError.
601
+ """
602
+ if question not in self.decide_later_items:
603
+ self.decide_later_items.append(question)
604
+
605
+ log.info(
606
+ "pm.question_decide_later_by_user",
607
+ question=question[:100],
608
+ )
609
+
610
+ return await self.record_response(
611
+ state,
612
+ user_response="[Decide later] To be determined — user chose to decide later.",
613
+ question=question,
614
+ )
615
+
616
+ async def skip_as_deferred(
617
+ self,
618
+ state: InterviewState,
619
+ question: str,
620
+ ) -> Result[InterviewState, ValidationError]:
621
+ """Skip a question as "deferred to dev" at the user's explicit request.
622
+
623
+ Records the question in ``deferred_items`` and feeds a deferral
624
+ response to the inner InterviewEngine so the round is properly recorded
625
+ and the engine advances.
626
+
627
+ Args:
628
+ state: Current interview state.
629
+ question: The question the user chose to defer.
630
+
631
+ Returns:
632
+ Result containing updated state or ValidationError.
633
+ """
634
+ if question not in self.deferred_items:
635
+ self.deferred_items.append(question)
636
+
637
+ log.info(
638
+ "pm.question_deferred_by_user",
639
+ question=question[:100],
640
+ )
641
+
642
+ return await self.record_response(
643
+ state,
644
+ user_response="[Deferred to development phase] "
645
+ "This technical decision will be addressed during the "
646
+ "development interview.",
647
+ question=question,
648
+ )
649
+
598
650
  async def complete_interview(
599
651
  self,
600
652
  state: InterviewState,
@@ -1129,13 +1181,14 @@ Include them as original question text in "decide_later_items":
1129
1181
  for s in data.get("user_stories", [])
1130
1182
  )
1131
1183
 
1132
- # Merge deferred items from classifier with extraction
1184
+ # Merge LLM-extracted items with engine-tracked items, deduplicating.
1185
+ # The extraction prompt includes raw items as context so the LLM may
1186
+ # already emit them, but engine-tracked items are authoritative and
1187
+ # must survive even if the extractor omits them.
1133
1188
  all_deferred = list(data.get("deferred_items", []))
1134
1189
  for item in self.deferred_items:
1135
1190
  if item not in all_deferred:
1136
1191
  all_deferred.append(item)
1137
-
1138
- # Merge decide-later items — stored as original question text
1139
1192
  all_decide_later = list(data.get("decide_later_items", []))
1140
1193
  for item in self.decide_later_items:
1141
1194
  if item not in all_decide_later:
@@ -3,9 +3,10 @@
3
3
  Classifies generated questions as PM-answerable (planning), DEV-only
4
4
  (development/technical), or decide-later (premature/unknowable).
5
5
 
6
- DEV-only questions are reframed into PM-friendly language or deferred to
7
- the development interview phase. Decide-later questions get an automatic
8
- placeholder response without PM interaction.
6
+ DEV-only questions are reframed into PM-friendly language or returned to
7
+ the user with the option to defer to the development interview phase.
8
+ Decide-later questions are returned to the user with the option to defer
9
+ rather than being automatically skipped.
9
10
 
10
11
  Uses a Sonnet-grade model for accurate judgment and reframing.
11
12
  """
@@ -51,8 +52,8 @@ class ClassifierOutputType(StrEnum):
51
52
 
52
53
  PASSTHROUGH: Planning question forwarded unchanged to the PM.
53
54
  REFRAMED: Development question rewritten in PM-friendly language.
54
- DEFERRED: Deeply technical question deferred to the dev interview phase.
55
- DECIDE_LATER: Premature question auto-answered with a placeholder.
55
+ DEFERRED: Deeply technical question returned to user with defer option.
56
+ DECIDE_LATER: Premature question returned to user with decide-later option.
56
57
  """
57
58
 
58
59
  PASSTHROUGH = "passthrough"
@@ -73,8 +74,9 @@ class ClassificationResult:
73
74
  reasoning: Why the classifier chose this category.
74
75
  defer_to_dev: Whether this question should be deferred entirely.
75
76
  decide_later: Whether this question is premature and should be
76
- auto-answered with a placeholder.
77
- placeholder_response: Automatic response for decide-later questions.
77
+ returned to the user with the option to defer.
78
+ placeholder_response: Placeholder response for decide-later questions
79
+ (used if the user chooses to defer).
78
80
  """
79
81
 
80
82
  original_question: str
@@ -90,8 +92,10 @@ class ClassificationResult:
90
92
  """Determine the classifier output type for this result.
91
93
 
92
94
  Returns:
93
- DECIDE_LATER if premature/unknowable question (auto-answered),
94
- DEFERRED if deeply technical (skipped entirely),
95
+ DECIDE_LATER if premature/unknowable question (returned to user
96
+ with option to defer),
97
+ DEFERRED if deeply technical (returned to user with option to
98
+ defer to dev phase),
95
99
  PASSTHROUGH if planning question (forwarded unchanged),
96
100
  REFRAMED if development question rewritten for PM.
97
101
  """
@@ -109,13 +113,20 @@ class ClassificationResult:
109
113
 
110
114
  For PASSTHROUGH: returns original_question unchanged.
111
115
  For REFRAMED: returns the reframed_question.
112
- For DEFERRED: returns empty string (should not be shown).
113
- For DECIDE_LATER: returns empty string (auto-answered).
116
+ For DEFERRED: returns original_question (shown to user
117
+ so they can choose to answer or defer to dev).
118
+ For DECIDE_LATER: returns original_question (shown to user
119
+ so they can choose to answer or defer).
114
120
  """
115
121
  if self.output_type == ClassifierOutputType.PASSTHROUGH:
116
122
  return self.original_question
117
123
  if self.output_type == ClassifierOutputType.REFRAMED:
118
124
  return self.reframed_question
125
+ if self.output_type in (
126
+ ClassifierOutputType.DECIDE_LATER,
127
+ ClassifierOutputType.DEFERRED,
128
+ ):
129
+ return self.original_question
119
130
  return ""
120
131
 
121
132
 
@@ -181,7 +192,8 @@ class QuestionClassifier:
181
192
 
182
193
  Uses a Sonnet-grade LLM to judge whether questions are appropriate
183
194
  for a PM audience, reframes technical questions when possible, and
184
- identifies premature questions that should be auto-answered.
195
+ identifies premature questions that should be returned to the user
196
+ with the option to defer.
185
197
 
186
198
  Attributes:
187
199
  llm_adapter: LLM adapter for classification calls.
@@ -17,6 +17,10 @@ from rich.prompt import Confirm, Prompt
17
17
  import typer
18
18
 
19
19
  from ouroboros.bigbang.interview import InterviewRound
20
+ from ouroboros.bigbang.pm_completion import (
21
+ build_pm_completion_summary,
22
+ maybe_complete_pm_interview,
23
+ )
20
24
  from ouroboros.cli.formatters import console
21
25
  from ouroboros.cli.formatters.panels import print_error, print_info, print_success, print_warning
22
26
  from ouroboros.cli.formatters.prompting import multiline_prompt_async
@@ -447,6 +451,20 @@ async def _run_pm_interview(
447
451
 
448
452
  console.print(f"\n[bold yellow]?[/] {question}\n")
449
453
 
454
+ # Check if this question was classified as skippable —
455
+ # if so, show a hint that the user can defer it.
456
+ classification = engine.get_last_classification()
457
+ if classification == "decide_later":
458
+ console.print(
459
+ "[dim] 💡 This question can be deferred. "
460
+ 'Type "decide later" or "skip" to defer it.[/]\n'
461
+ )
462
+ elif classification == "deferred":
463
+ console.print(
464
+ "[dim] 💡 This is a technical question that can be deferred to the dev phase. "
465
+ 'Type "defer" or "skip" to defer it.[/]\n'
466
+ )
467
+
450
468
  # Persist state + meta AFTER displaying the question but BEFORE
451
469
  # waiting for input so that an interruption preserves the pending
452
470
  # question and --resume shows the same question.
@@ -465,15 +483,30 @@ async def _run_pm_interview(
465
483
  # so extraction never sees a question the user didn't answer.
466
484
  if state.rounds and state.rounds[-1].user_response is None:
467
485
  state.rounds.pop()
486
+
487
+ completion = await engine.check_completion(state)
468
488
  complete_result = await engine.complete_interview(state)
469
- if isinstance(complete_result, Result) and complete_result.is_err:
489
+ if complete_result.is_err:
470
490
  print_error(f"Failed to complete interview: {complete_result.error}")
471
- elif isinstance(complete_result, Result):
472
- state = complete_result.value
491
+ break
492
+
493
+ state = complete_result.value
473
494
  save_result = await engine.save_state(state)
474
- if isinstance(save_result, Result) and save_result.is_err:
495
+ if save_result.is_err:
475
496
  print_error(f"Failed to save completed state: {save_result.error}")
497
+ break
476
498
  _save_cli_pm_meta(state.interview_id, engine)
499
+
500
+ decide_later_summary = engine.format_decide_later_summary()
501
+ summary_text = build_pm_completion_summary(
502
+ session_id=state.interview_id,
503
+ completion=completion,
504
+ stored_ambiguity_score=state.ambiguity_score,
505
+ deferred_count=len(engine.deferred_items),
506
+ decide_later_count=len(engine.decide_later_items),
507
+ decide_later_summary=decide_later_summary,
508
+ )
509
+ console.print(f"\n[bold green]{summary_text}[/]\n")
477
510
  break
478
511
 
479
512
  # Pop the unanswered round before recording so record_response
@@ -481,12 +514,72 @@ async def _run_pm_interview(
481
514
  if state.rounds and state.rounds[-1].user_response is None:
482
515
  state.rounds.pop()
483
516
 
517
+ # Handle user-initiated skip (decide later / defer to dev)
518
+ _lower = user_response.strip().lower()
519
+ if classification == "decide_later" and _lower in (
520
+ "decide later",
521
+ "skip",
522
+ "[decide_later]",
523
+ ):
524
+ record_result = await engine.skip_as_decide_later(state, question)
525
+ if isinstance(record_result, Result) and record_result.is_err:
526
+ print_error(f"Failed to skip question: {record_result.error}")
527
+ break
528
+ save_result = await engine.save_state(state)
529
+ if isinstance(save_result, Result) and save_result.is_err:
530
+ print_error(f"Failed to save state: {save_result.error}")
531
+ break
532
+ _save_cli_pm_meta(state.interview_id, engine)
533
+ continue
534
+ if classification == "deferred" and _lower in (
535
+ "defer",
536
+ "skip",
537
+ "[deferred]",
538
+ ):
539
+ record_result = await engine.skip_as_deferred(state, question)
540
+ if isinstance(record_result, Result) and record_result.is_err:
541
+ print_error(f"Failed to defer question: {record_result.error}")
542
+ break
543
+ save_result = await engine.save_state(state)
544
+ if isinstance(save_result, Result) and save_result.is_err:
545
+ print_error(f"Failed to save state: {save_result.error}")
546
+ break
547
+ _save_cli_pm_meta(state.interview_id, engine)
548
+ continue
549
+
484
550
  record_result = await engine.record_response(state, user_response, question)
485
551
  if isinstance(record_result, Result) and record_result.is_err:
486
552
  print_error(f"Failed to record response: {record_result.error}")
487
553
  break
488
554
  if isinstance(record_result, Result):
489
555
  state = record_result.value
556
+
557
+ state.clear_stored_ambiguity()
558
+ completion_result = await maybe_complete_pm_interview(state, engine)
559
+ if completion_result.is_err:
560
+ print_error(f"Failed to complete interview: {completion_result.error}")
561
+ break
562
+
563
+ state, completion = completion_result.value
564
+ if completion is not None:
565
+ save_result = await engine.save_state(state)
566
+ if save_result.is_err:
567
+ print_error(f"Failed to save completed state: {save_result.error}")
568
+ break
569
+ _save_cli_pm_meta(state.interview_id, engine)
570
+
571
+ decide_later_summary = engine.format_decide_later_summary()
572
+ summary_text = build_pm_completion_summary(
573
+ session_id=state.interview_id,
574
+ completion=completion,
575
+ stored_ambiguity_score=state.ambiguity_score,
576
+ deferred_count=len(engine.deferred_items),
577
+ decide_later_count=len(engine.decide_later_items),
578
+ decide_later_summary=decide_later_summary,
579
+ )
580
+ console.print(f"\n[bold green]{summary_text}[/]\n")
581
+ break
582
+
490
583
  save_result = await engine.save_state(state)
491
584
  if isinstance(save_result, Result) and save_result.is_err:
492
585
  print_error(f"Failed to save state: {save_result.error}")