ouroboros-ai 0.26.5.dev7__tar.gz → 0.26.5.dev9__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 (574) hide show
  1. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/PKG-INFO +1 -1
  2. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/_version.py +2 -2
  3. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/pm_completion.py +1 -2
  4. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/pm_document.py +3 -3
  5. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/pm_interview.py +44 -31
  6. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/pm_seed.py +96 -49
  7. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/pm.py +12 -6
  8. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/pm_handler.py +16 -9
  9. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/claude_code_adapter.py +44 -8
  10. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/codex_cli_adapter.py +14 -4
  11. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/factory.py +10 -1
  12. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_decide_later_items.py +8 -8
  13. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_pm_document_generator.py +1 -2
  14. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_pm_document_writer.py +1 -2
  15. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_pm_interview.py +11 -10
  16. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +3 -2
  17. ouroboros_ai-0.26.5.dev9/tests/unit/bigbang/test_pm_seed_ac12.py +242 -0
  18. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_pm_seed_save.py +17 -13
  19. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_init_pm_seed_detection.py +5 -11
  20. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_pm_handler.py +24 -20
  21. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_pm_handler_generate.py +1 -2
  22. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/pm/test_renderer.py +1 -2
  23. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/providers/test_claude_code_adapter.py +63 -0
  24. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/providers/test_codex_cli_adapter.py +20 -0
  25. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/providers/test_factory.py +35 -0
  26. ouroboros_ai-0.26.5.dev7/tests/unit/bigbang/test_pm_seed_ac12.py +0 -265
  27. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.claude/settings.json +0 -0
  28. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.claude-plugin/.mcp.json +0 -0
  29. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.claude-plugin/marketplace.json +0 -0
  30. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.claude-plugin/plugin.json +0 -0
  31. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.env.example +0 -0
  32. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  33. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  34. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  35. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  36. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/workflows/dev-publish.yml +0 -0
  37. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/workflows/lint.yml +0 -0
  38. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/workflows/release.yml +0 -0
  39. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.github/workflows/test.yml +0 -0
  40. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.gitignore +0 -0
  41. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.mcp.json +0 -0
  42. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.ouroboros/mechanical.toml +0 -0
  43. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.pre-commit-config.yaml +0 -0
  44. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/.python-version +0 -0
  45. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/CHANGELOG.md +0 -0
  46. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/CLAUDE.md +0 -0
  47. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/CODE_OF_CONDUCT.md +0 -0
  48. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/CONTRIBUTING.md +0 -0
  49. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/HANDOFF.md +0 -0
  50. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/LICENSE +0 -0
  51. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/README.ko.md +0 -0
  52. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/README.md +0 -0
  53. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/SECURITY.md +0 -0
  54. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/UNINSTALL.md +0 -0
  55. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/cancel.md +0 -0
  56. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/evaluate.md +0 -0
  57. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/evolve.md +0 -0
  58. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/help.md +0 -0
  59. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/interview.md +0 -0
  60. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/ralph.md +0 -0
  61. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/run.md +0 -0
  62. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/seed.md +0 -0
  63. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/setup.md +0 -0
  64. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/status.md +0 -0
  65. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/tutorial.md +0 -0
  66. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/unstuck.md +0 -0
  67. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/commands/welcome.md +0 -0
  68. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/.gitignore +0 -0
  69. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/Cargo.lock +0 -0
  70. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/Cargo.toml +0 -0
  71. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/README.md +0 -0
  72. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/db.rs +0 -0
  73. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/main.rs +0 -0
  74. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/mock.rs +0 -0
  75. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/state.rs +0 -0
  76. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
  77. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/views/execution.rs +0 -0
  78. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
  79. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/views/logs.rs +0 -0
  80. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/views/mod.rs +0 -0
  81. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
  82. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/README.md +0 -0
  83. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/api/README.md +0 -0
  84. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/api/core.md +0 -0
  85. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/api/mcp.md +0 -0
  86. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/architecture.md +0 -0
  87. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/cli-reference.md +0 -0
  88. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/config-reference.md +0 -0
  89. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/contributing/architecture-overview.md +0 -0
  90. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/contributing/findings-registry.md +0 -0
  91. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/contributing/issue-quality-policy.md +0 -0
  92. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/contributing/key-patterns.md +0 -0
  93. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/contributing/testing-guide.md +0 -0
  94. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/examples/mcp-config.yaml +0 -0
  95. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/getting-started.md +0 -0
  96. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/guides/evaluation-pipeline.md +0 -0
  97. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/guides/evolution-loop.md +0 -0
  98. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
  99. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/guides/seed-authoring.md +0 -0
  100. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/guides/tui-usage.md +0 -0
  101. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/images/PLACEHOLDER_README.md +0 -0
  102. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/images/ouroboros.png +0 -0
  103. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/platform-support.md +0 -0
  104. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/runtime-capability-matrix.md +0 -0
  105. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/runtime-guides/claude-code.md +0 -0
  106. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/docs/runtime-guides/codex.md +0 -0
  107. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/coordinator_test_seed.yaml +0 -0
  108. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/dummy_seed.yaml +0 -0
  109. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/parallel_subac_test_seed.yaml +0 -0
  110. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/subac_test_seed.yaml +0 -0
  111. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/task_manager/README.md +0 -0
  112. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/task_manager/__init__.py +0 -0
  113. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/task_manager/__main__.py +0 -0
  114. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/task_manager/cli.py +0 -0
  115. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/task_manager/models.py +0 -0
  116. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/task_manager/storage.py +0 -0
  117. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/examples/test_display.py +0 -0
  118. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/hooks/hooks.json +0 -0
  119. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/llms-full.txt +0 -0
  120. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/llms.txt +0 -0
  121. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/project-context.md +0 -0
  122. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/pyproject.toml +0 -0
  123. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/drift-monitor.py +0 -0
  124. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/install.sh +0 -0
  125. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/keyword-detector.py +0 -0
  126. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/mcp-serve.sh +0 -0
  127. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/ralph-rewind.py +0 -0
  128. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/ralph.py +0 -0
  129. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/ralph.sh +0 -0
  130. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/session-start.py +0 -0
  131. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/sync-plugin-version.py +0 -0
  132. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/scripts/version-check.py +0 -0
  133. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/brownfield/SKILL.md +0 -0
  134. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/cancel/SKILL.md +0 -0
  135. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/evaluate/SKILL.md +0 -0
  136. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/evolve/SKILL.md +0 -0
  137. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/help/SKILL.md +0 -0
  138. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/interview/SKILL.md +0 -0
  139. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/pm/SKILL.md +0 -0
  140. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/qa/SKILL.md +0 -0
  141. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/ralph/SKILL.md +0 -0
  142. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/run/SKILL.md +0 -0
  143. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/seed/SKILL.md +0 -0
  144. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/setup/SKILL.md +0 -0
  145. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/status/SKILL.md +0 -0
  146. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/tutorial/SKILL.md +0 -0
  147. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/unstuck/SKILL.md +0 -0
  148. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/update/SKILL.md +0 -0
  149. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/skills/welcome/SKILL.md +0 -0
  150. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/__init__.py +0 -0
  151. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/__main__.py +0 -0
  152. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/__init__.py +0 -0
  153. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/advocate.md +0 -0
  154. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/analysis-agent.md +0 -0
  155. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/architect.md +0 -0
  156. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/breadth-keeper.md +0 -0
  157. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/code-executor.md +0 -0
  158. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/codebase-explorer.md +0 -0
  159. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/consensus-reviewer.md +0 -0
  160. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/contrarian.md +0 -0
  161. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/evaluator.md +0 -0
  162. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/hacker.md +0 -0
  163. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/judge.md +0 -0
  164. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/loader.py +0 -0
  165. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/ontologist.md +0 -0
  166. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/ontology-analyst.md +0 -0
  167. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/qa-judge.md +0 -0
  168. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/research-agent.md +0 -0
  169. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/researcher.md +0 -0
  170. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/seed-architect.md +0 -0
  171. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/seed-closer.md +0 -0
  172. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/semantic-evaluator.md +0 -0
  173. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/simplifier.md +0 -0
  174. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/agents/socratic-interviewer.md +0 -0
  175. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/__init__.py +0 -0
  176. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/ambiguity.py +0 -0
  177. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/brownfield.py +0 -0
  178. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/explore.py +0 -0
  179. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/interview.py +0 -0
  180. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/question_classifier.py +0 -0
  181. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/bigbang/seed_generator.py +0 -0
  182. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/__init__.py +0 -0
  183. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/__init__.py +0 -0
  184. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/cancel.py +0 -0
  185. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/config.py +0 -0
  186. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/init.py +0 -0
  187. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/mcp.py +0 -0
  188. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/run.py +0 -0
  189. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/setup.py +0 -0
  190. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/status.py +0 -0
  191. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/tui.py +0 -0
  192. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/commands/uninstall.py +0 -0
  193. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/formatters/__init__.py +0 -0
  194. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/formatters/panels.py +0 -0
  195. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/formatters/progress.py +0 -0
  196. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/formatters/prompting.py +0 -0
  197. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/formatters/tables.py +0 -0
  198. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
  199. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/cli/main.py +0 -0
  200. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/codex/__init__.py +0 -0
  201. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/codex/artifacts.py +0 -0
  202. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/codex/ouroboros.md +0 -0
  203. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/codex_permissions.py +0 -0
  204. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/config/__init__.py +0 -0
  205. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/config/loader.py +0 -0
  206. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/config/models.py +0 -0
  207. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/__init__.py +0 -0
  208. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/ac_tree.py +0 -0
  209. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/context.py +0 -0
  210. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/errors.py +0 -0
  211. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/file_lock.py +0 -0
  212. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/git_workflow.py +0 -0
  213. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/initial_context.py +0 -0
  214. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/lineage.py +0 -0
  215. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/ontology_aspect.py +0 -0
  216. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/ontology_questions.py +0 -0
  217. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/project_paths.py +0 -0
  218. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/security.py +0 -0
  219. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/seed.py +0 -0
  220. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/text.py +0 -0
  221. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/types.py +0 -0
  222. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/core/worktree.py +0 -0
  223. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/__init__.py +0 -0
  224. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/artifact_collector.py +0 -0
  225. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/consensus.py +0 -0
  226. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/json_utils.py +0 -0
  227. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/languages.py +0 -0
  228. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/mechanical.py +0 -0
  229. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/models.py +0 -0
  230. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/pipeline.py +0 -0
  231. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/semantic.py +0 -0
  232. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/trigger.py +0 -0
  233. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
  234. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/__init__.py +0 -0
  235. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/base.py +0 -0
  236. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/decomposition.py +0 -0
  237. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/evaluation.py +0 -0
  238. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/interview.py +0 -0
  239. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/lineage.py +0 -0
  240. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/events/ontology.py +0 -0
  241. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/__init__.py +0 -0
  242. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/convergence.py +0 -0
  243. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/loop.py +0 -0
  244. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/projector.py +0 -0
  245. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/reflect.py +0 -0
  246. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/regression.py +0 -0
  247. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/evolution/wonder.py +0 -0
  248. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/execution/__init__.py +0 -0
  249. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/execution/atomicity.py +0 -0
  250. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/execution/decomposition.py +0 -0
  251. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/execution/double_diamond.py +0 -0
  252. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/execution/subagent.py +0 -0
  253. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/__init__.py +0 -0
  254. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/client/__init__.py +0 -0
  255. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/client/adapter.py +0 -0
  256. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/client/manager.py +0 -0
  257. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/client/protocol.py +0 -0
  258. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/errors.py +0 -0
  259. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/job_manager.py +0 -0
  260. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/resources/__init__.py +0 -0
  261. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/resources/handlers.py +0 -0
  262. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/server/__init__.py +0 -0
  263. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/server/adapter.py +0 -0
  264. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/server/protocol.py +0 -0
  265. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/server/security.py +0 -0
  266. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/__init__.py +0 -0
  267. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
  268. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
  269. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/dashboard.py +0 -0
  270. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/definitions.py +0 -0
  271. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
  272. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
  273. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
  274. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
  275. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/qa.py +0 -0
  276. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
  277. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/tools/registry.py +0 -0
  278. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/mcp/types.py +0 -0
  279. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/observability/__init__.py +0 -0
  280. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/observability/drift.py +0 -0
  281. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/observability/logging.py +0 -0
  282. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/observability/retrospective.py +0 -0
  283. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/__init__.py +0 -0
  284. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/adapter.py +0 -0
  285. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
  286. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
  287. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/coordinator.py +0 -0
  288. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
  289. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/events.py +0 -0
  290. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
  291. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
  292. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/heartbeat.py +0 -0
  293. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/level_context.py +0 -0
  294. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/mcp_config.py +0 -0
  295. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
  296. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
  297. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
  298. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/runner.py +0 -0
  299. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
  300. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
  301. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/session.py +0 -0
  302. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/orchestrator/workflow_state.py +0 -0
  303. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/__init__.py +0 -0
  304. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/brownfield.py +0 -0
  305. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/checkpoint.py +0 -0
  306. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/event_store.py +0 -0
  307. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/migrations/__init__.py +0 -0
  308. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/migrations/runner.py +0 -0
  309. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
  310. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
  311. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/schema.py +0 -0
  312. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/persistence/uow.py +0 -0
  313. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/__init__.py +0 -0
  314. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/agents/__init__.py +0 -0
  315. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/agents/pool.py +0 -0
  316. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/agents/registry.py +0 -0
  317. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
  318. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/orchestration/router.py +0 -0
  319. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
  320. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/skills/__init__.py +0 -0
  321. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/skills/docs.py +0 -0
  322. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/skills/executor.py +0 -0
  323. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/skills/keywords.py +0 -0
  324. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/plugin/skills/registry.py +0 -0
  325. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/pm/__init__.py +0 -0
  326. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/pm/handoff.py +0 -0
  327. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/pm/renderer.py +0 -0
  328. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/__init__.py +0 -0
  329. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/anthropic_adapter.py +0 -0
  330. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/base.py +0 -0
  331. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/codex_cli_stream.py +0 -0
  332. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/providers/litellm_adapter.py +0 -0
  333. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/py.typed +0 -0
  334. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/resilience/__init__.py +0 -0
  335. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/resilience/lateral.py +0 -0
  336. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/resilience/stagnation.py +0 -0
  337. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/routing/__init__.py +0 -0
  338. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/routing/complexity.py +0 -0
  339. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/routing/downgrade.py +0 -0
  340. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/routing/escalation.py +0 -0
  341. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/routing/router.py +0 -0
  342. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/routing/tiers.py +0 -0
  343. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/secondary/__init__.py +0 -0
  344. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/secondary/scheduler.py +0 -0
  345. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/secondary/todo_registry.py +0 -0
  346. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/strategies/__init__.py +0 -0
  347. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/strategies/devil_advocate.py +0 -0
  348. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/__init__.py +0 -0
  349. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/app.py +0 -0
  350. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/components/__init__.py +0 -0
  351. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/components/agents_panel.py +0 -0
  352. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/components/event_log.py +0 -0
  353. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/components/progress.py +0 -0
  354. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/components/token_tracker.py +0 -0
  355. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/events.py +0 -0
  356. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/__init__.py +0 -0
  357. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
  358. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/dashboard.py +0 -0
  359. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
  360. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
  361. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/debug.py +0 -0
  362. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/execution.py +0 -0
  363. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
  364. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
  365. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
  366. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/logs.py +0 -0
  367. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/screens/session_selector.py +0 -0
  368. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/__init__.py +0 -0
  369. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
  370. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
  371. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
  372. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
  373. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
  374. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
  375. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
  376. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
  377. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/verification/__init__.py +0 -0
  378. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/verification/extractor.py +0 -0
  379. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/verification/models.py +0 -0
  380. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/src/ouroboros/verification/verifier.py +0 -0
  381. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/__init__.py +0 -0
  382. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/conftest.py +0 -0
  383. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/e2e/__init__.py +0 -0
  384. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/e2e/conftest.py +0 -0
  385. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/e2e/test_cli_commands.py +0 -0
  386. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/e2e/test_full_workflow.py +0 -0
  387. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/e2e/test_session_persistence.py +0 -0
  388. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/fixtures/test_atomicity_seed.yml +0 -0
  389. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/__init__.py +0 -0
  390. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/conftest.py +0 -0
  391. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/mcp/__init__.py +0 -0
  392. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/mcp/conftest.py +0 -0
  393. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/mcp/test_client_adapter.py +0 -0
  394. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/mcp/test_client_manager.py +0 -0
  395. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/mcp/test_server_adapter.py +0 -0
  396. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/plugin/test_orchestration.py +0 -0
  397. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
  398. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/test_codex_skill_fallback.py +0 -0
  399. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/test_codex_skill_smoke.py +0 -0
  400. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/integration/test_entry_point.py +0 -0
  401. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/__init__.py +0 -0
  402. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/agents/__init__.py +0 -0
  403. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/agents/test_loader.py +0 -0
  404. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/__init__.py +0 -0
  405. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_ambiguity.py +0 -0
  406. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_brownfield.py +0 -0
  407. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_classifier_context.py +0 -0
  408. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_explore.py +0 -0
  409. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_interview.py +0 -0
  410. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_pm_completion.py +0 -0
  411. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_question_classifier.py +0 -0
  412. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/bigbang/test_seed_generator.py +0 -0
  413. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/__init__.py +0 -0
  414. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/__init__.py +0 -0
  415. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/test_console.py +0 -0
  416. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/test_panels.py +0 -0
  417. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/test_progress.py +0 -0
  418. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/test_prompting.py +0 -0
  419. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/test_tables.py +0 -0
  420. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
  421. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_cancel.py +0 -0
  422. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_config.py +0 -0
  423. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_init_runtime.py +0 -0
  424. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_main.py +0 -0
  425. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
  426. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
  427. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm.py +0 -0
  428. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_brownfield.py +0 -0
  429. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_completion.py +0 -0
  430. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_interactive_logging.py +0 -0
  431. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
  432. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_overwrite.py +0 -0
  433. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_runtime_adapter.py +0 -0
  434. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_pm_select_repos.py +0 -0
  435. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_run_qa.py +0 -0
  436. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_setup.py +0 -0
  437. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/cli/test_uninstall.py +0 -0
  438. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/config/__init__.py +0 -0
  439. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/config/test_loader.py +0 -0
  440. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/config/test_models.py +0 -0
  441. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/__init__.py +0 -0
  442. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_ac_tree.py +0 -0
  443. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_context.py +0 -0
  444. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_errors.py +0 -0
  445. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_git_workflow.py +0 -0
  446. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_initial_context.py +0 -0
  447. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_lineage.py +0 -0
  448. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_ontology_aspect.py +0 -0
  449. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_ontology_questions.py +0 -0
  450. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_security.py +0 -0
  451. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_seed.py +0 -0
  452. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_types.py +0 -0
  453. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/core/test_worktree.py +0 -0
  454. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/__init__.py +0 -0
  455. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_consensus.py +0 -0
  456. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_json_utils.py +0 -0
  457. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_languages.py +0 -0
  458. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_mechanical.py +0 -0
  459. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_models.py +0 -0
  460. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_semantic.py +0 -0
  461. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_trigger.py +0 -0
  462. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
  463. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/events/__init__.py +0 -0
  464. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/events/test_base.py +0 -0
  465. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/events/test_decomposition_events.py +0 -0
  466. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/evolution/test_wonder_scope.py +0 -0
  467. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/execution/__init__.py +0 -0
  468. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/execution/test_atomicity.py +0 -0
  469. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/execution/test_decomposition.py +0 -0
  470. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/execution/test_double_diamond.py +0 -0
  471. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/execution/test_subagent_isolation.py +0 -0
  472. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/__init__.py +0 -0
  473. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/client/__init__.py +0 -0
  474. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/client/test_adapter.py +0 -0
  475. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/client/test_manager.py +0 -0
  476. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/conftest.py +0 -0
  477. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/server/__init__.py +0 -0
  478. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/server/test_adapter.py +0 -0
  479. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/server/test_security.py +0 -0
  480. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/test_errors.py +0 -0
  481. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/test_job_manager.py +0 -0
  482. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/test_types.py +0 -0
  483. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/__init__.py +0 -0
  484. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/conftest.py +0 -0
  485. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
  486. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_definitions.py +0 -0
  487. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
  488. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
  489. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/mcp/tools/test_registry.py +0 -0
  490. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/observability/__init__.py +0 -0
  491. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/observability/test_drift.py +0 -0
  492. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/observability/test_logging.py +0 -0
  493. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/observability/test_retrospective.py +0 -0
  494. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/__init__.py +0 -0
  495. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_adapter.py +0 -0
  496. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
  497. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
  498. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
  499. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_coordinator.py +0 -0
  500. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
  501. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_events.py +0 -0
  502. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
  503. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
  504. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
  505. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_level_context.py +0 -0
  506. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_mcp_config.py +0 -0
  507. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
  508. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
  509. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
  510. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_runner.py +0 -0
  511. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
  512. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
  513. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
  514. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_session.py +0 -0
  515. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/orchestrator/test_workflow_state.py +0 -0
  516. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/persistence/__init__.py +0 -0
  517. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/persistence/test_brownfield_store.py +0 -0
  518. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/persistence/test_checkpoint.py +0 -0
  519. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/persistence/test_event_store.py +0 -0
  520. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/persistence/test_schema.py +0 -0
  521. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/persistence/test_uow.py +0 -0
  522. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/__init__.py +0 -0
  523. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/agents/__init__.py +0 -0
  524. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/agents/test_registry.py +0 -0
  525. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/orchestration/__init__.py +0 -0
  526. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
  527. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/skills/__init__.py +0 -0
  528. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/skills/test_keywords.py +0 -0
  529. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/plugin/skills/test_registry.py +0 -0
  530. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/pm/__init__.py +0 -0
  531. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/providers/__init__.py +0 -0
  532. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/providers/test_base.py +0 -0
  533. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/providers/test_litellm_adapter.py +0 -0
  534. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/resilience/__init__.py +0 -0
  535. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/resilience/test_lateral.py +0 -0
  536. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/resilience/test_stagnation.py +0 -0
  537. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/routing/__init__.py +0 -0
  538. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/routing/test_complexity.py +0 -0
  539. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/routing/test_downgrade.py +0 -0
  540. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/routing/test_escalation.py +0 -0
  541. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/routing/test_router.py +0 -0
  542. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/routing/test_tiers.py +0 -0
  543. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/scripts/test_keyword_detector.py +0 -0
  544. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/scripts/test_version_check.py +0 -0
  545. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/secondary/__init__.py +0 -0
  546. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/secondary/test_scheduler.py +0 -0
  547. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/secondary/test_todo_registry.py +0 -0
  548. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_artifact_collector.py +0 -0
  549. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_codex_artifacts.py +0 -0
  550. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_convergence.py +0 -0
  551. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_dashboard.py +0 -0
  552. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_dependencies_configured.py +0 -0
  553. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_evolve_rewind.py +0 -0
  554. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_evolve_step.py +0 -0
  555. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_graceful_shutdown.py +0 -0
  556. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_main_entry_point.py +0 -0
  557. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_module_structure.py +0 -0
  558. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_project_initialization.py +0 -0
  559. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_projector_rewind.py +0 -0
  560. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_ralph_parser.py +0 -0
  561. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_ralph_rewind.py +0 -0
  562. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_regression.py +0 -0
  563. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_tooling_configuration.py +0 -0
  564. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/test_verification.py +0 -0
  565. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/__init__.py +0 -0
  566. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_app.py +0 -0
  567. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_cancelled_display.py +0 -0
  568. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_events.py +0 -0
  569. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_lineage_viewer.py +0 -0
  570. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_screens.py +0 -0
  571. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_session_selector_replay.py +0 -0
  572. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tests/unit/tui/test_widgets.py +0 -0
  573. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/tools/sync_github_project.py +0 -0
  574. {ouroboros_ai-0.26.5.dev7 → ouroboros_ai-0.26.5.dev9}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ouroboros-ai
3
- Version: 0.26.5.dev7
3
+ Version: 0.26.5.dev9
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
@@ -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.dev7'
22
- __version_tuple__ = version_tuple = (0, 26, 5, 'dev7')
21
+ __version__ = version = '0.26.5.dev9'
22
+ __version_tuple__ = version_tuple = (0, 26, 5, 'dev9')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -49,8 +49,7 @@ def build_pm_completion_summary(
49
49
  lines.append(f"Ambiguity score: {ambiguity_score:.2f}")
50
50
 
51
51
  lines.append("")
52
- lines.append(f"Deferred items: {deferred_count}")
53
- lines.append(f"Decide-later items: {decide_later_count}")
52
+ lines.append(f"Decide-later items: {deferred_count + decide_later_count}")
54
53
 
55
54
  if decide_later_summary:
56
55
  lines.append("")
@@ -130,8 +130,8 @@ def generate_pm_markdown(seed: PMSeed) -> str:
130
130
  lines.append(f"- {assumption}")
131
131
  lines.append("")
132
132
 
133
- # Decide Later (merged: deferred + decide-later)
134
- all_decide_later = list(seed.deferred_items or []) + list(seed.decide_later_items or [])
133
+ # Decide Later
134
+ all_decide_later = list(seed.decide_later_items or [])
135
135
  if all_decide_later:
136
136
  lines.append("## Decide Later")
137
137
  lines.append("")
@@ -439,7 +439,7 @@ class PMDocumentGenerator:
439
439
  parts.append(f"- {a}")
440
440
  parts.append("")
441
441
 
442
- all_decide_later = list(seed.deferred_items or []) + list(seed.decide_later_items or [])
442
+ all_decide_later = list(seed.decide_later_items or [])
443
443
  if all_decide_later:
444
444
  parts.append("**Decide Later:**")
445
445
  for item in all_decide_later:
@@ -664,16 +664,20 @@ class PMInterviewEngine:
664
664
  return await self.inner.complete_interview(state)
665
665
 
666
666
  def get_decide_later_summary(self) -> list[str]:
667
- """Return the list of decide-later items collected during the interview.
667
+ """Return the combined list of deferred + decide-later items.
668
668
 
669
- These are the original question texts for questions classified as
670
- DECIDE_LATER — premature or unknowable at the PM stage. Shown to
671
- the PM at interview end so they have a clear record of open items.
669
+ Merges runtime ``deferred_items`` (technical questions deferred to
670
+ dev phase) with ``decide_later_items`` (premature/unknowable questions)
671
+ into one canonical list for display and artifact generation.
672
672
 
673
673
  Returns:
674
674
  List of original question text strings. Empty if none were deferred.
675
675
  """
676
- return list(self.decide_later_items)
676
+ combined = list(self.decide_later_items)
677
+ for item in self.deferred_items:
678
+ if item not in combined:
679
+ combined.append(item)
680
+ return combined
677
681
 
678
682
  def format_decide_later_summary(self) -> str:
679
683
  """Format decide-later items as a human-readable summary string.
@@ -730,7 +734,7 @@ class PMInterviewEngine:
730
734
  def restore_meta(self, meta: dict[str, Any]) -> None:
731
735
  """Restore PM-specific metadata into this engine from a loaded dict.
732
736
 
733
- Sets ``deferred_items``, ``decide_later_items``, ``codebase_context``,
737
+ Sets ``decide_later_items``, ``codebase_context``,
734
738
  ``pending_reframe`` (via ``_reframe_map``), and syncs the classifier's
735
739
  ``codebase_context`` so that subsequent classification calls use the
736
740
  brownfield context.
@@ -740,12 +744,19 @@ class PMInterviewEngine:
740
744
 
741
745
  Args:
742
746
  meta: Dictionary previously persisted as ``pm_meta_{session_id}.json``.
743
- Expected keys: ``deferred_items``, ``decide_later_items``,
747
+ Expected keys: ``decide_later_items``,
744
748
  ``codebase_context``, ``pending_reframe``.
749
+ Legacy key ``deferred_items`` is merged into
750
+ ``decide_later_items`` for backward compatibility.
745
751
  """
746
- # Full state reset — clear all session-scoped fields before restoring
747
- self.deferred_items = list(meta.get("deferred_items", []))
752
+ # Full state reset — clear all session-scoped fields before restoring.
753
+ # Legacy metadata may still have separate deferred_items; merge them
754
+ # into decide_later_items (canonical field since v0.25).
748
755
  self.decide_later_items = list(meta.get("decide_later_items", []))
756
+ for item in meta.get("deferred_items", []):
757
+ if item not in self.decide_later_items:
758
+ self.decide_later_items.append(item)
759
+ self.deferred_items = []
749
760
  self.codebase_context = meta.get("codebase_context", "") or ""
750
761
  self.classifications = [] # Reset before restoring
751
762
  self._reframe_map = {} # Reset before restoring
@@ -803,8 +814,8 @@ class PMInterviewEngine:
803
814
  new items were added during classification. Returns a dict with:
804
815
  new_deferred: list of newly deferred question texts
805
816
  new_decide_later: list of newly decide-later question texts
806
- deferred_count: total deferred items
807
- decide_later_count: total decide-later items
817
+ deferred_count: always 0 (deprecated; merged into decide_later_count)
818
+ decide_later_count: combined total of deferred + decide-later items
808
819
 
809
820
  Args:
810
821
  deferred_len_before: Length of deferred_items before the call.
@@ -819,8 +830,8 @@ class PMInterviewEngine:
819
830
  return {
820
831
  "new_deferred": list(new_deferred),
821
832
  "new_decide_later": list(new_decide_later),
822
- "deferred_count": len(self.deferred_items),
823
- "decide_later_count": len(self.decide_later_items),
833
+ "deferred_count": 0,
834
+ "decide_later_count": len(self.deferred_items) + len(self.decide_later_items),
824
835
  }
825
836
 
826
837
  def get_pending_reframe(self) -> dict[str, str] | None:
@@ -1009,7 +1020,7 @@ class PMInterviewEngine:
1009
1020
  pm_id=seed.pm_id,
1010
1021
  product_name=seed.product_name,
1011
1022
  story_count=len(seed.user_stories),
1012
- deferred_count=len(seed.deferred_items),
1023
+ decide_later_count=len(seed.decide_later_items),
1013
1024
  )
1014
1025
  return Result.ok(seed)
1015
1026
  except (ValueError, KeyError, json.JSONDecodeError) as e:
@@ -1115,22 +1126,21 @@ class PMInterviewEngine:
1115
1126
  ---
1116
1127
  """
1117
1128
 
1118
- if self.deferred_items:
1119
- deferred_text = "\n".join(f"- {item}" for item in self.deferred_items)
1120
- prompt += f"""
1121
-
1122
- The following technical questions were deferred during the interview.
1123
- Include them in "deferred_items":
1124
- {deferred_text}
1125
- """
1129
+ # Combine deferred and decide-later items under one canonical key
1130
+ # so the LLM output schema matches PMSeed (which only has
1131
+ # decide_later_items).
1132
+ all_decide_later: list[str] = list(self.deferred_items)
1133
+ for item in self.decide_later_items:
1134
+ if item not in all_decide_later:
1135
+ all_decide_later.append(item)
1126
1136
 
1127
- if self.decide_later_items:
1128
- decide_later_text = "\n".join(f"- {item}" for item in self.decide_later_items)
1137
+ if all_decide_later:
1138
+ items_text = "\n".join(f"- {item}" for item in all_decide_later)
1129
1139
  prompt += f"""
1130
1140
 
1131
- The following questions were identified as premature or unknowable at this stage.
1141
+ The following questions were deferred or identified as premature during the interview.
1132
1142
  Include them as original question text in "decide_later_items":
1133
- {decide_later_text}
1143
+ {items_text}
1134
1144
  """
1135
1145
 
1136
1146
  # Note: brownfield codebase context is already included in
@@ -1185,11 +1195,15 @@ Include them as original question text in "decide_later_items":
1185
1195
  # The extraction prompt includes raw items as context so the LLM may
1186
1196
  # already emit them, but engine-tracked items are authoritative and
1187
1197
  # must survive even if the extractor omits them.
1188
- all_deferred = list(data.get("deferred_items", []))
1189
- for item in self.deferred_items:
1190
- if item not in all_deferred:
1191
- all_deferred.append(item)
1198
+ # Both deferred_items (from LLM) and engine.deferred_items are merged
1199
+ # into decide_later_items on the PMSeed.
1192
1200
  all_decide_later = list(data.get("decide_later_items", []))
1201
+ for item in data.get("deferred_items", []):
1202
+ if item not in all_decide_later:
1203
+ all_decide_later.append(item)
1204
+ for item in self.deferred_items:
1205
+ if item not in all_decide_later:
1206
+ all_decide_later.append(item)
1193
1207
  for item in self.decide_later_items:
1194
1208
  if item not in all_decide_later:
1195
1209
  all_decide_later.append(item)
@@ -1204,7 +1218,6 @@ Include them as original question text in "decide_later_items":
1204
1218
  user_stories=stories,
1205
1219
  constraints=tuple(data.get("constraints", [])),
1206
1220
  success_criteria=tuple(data.get("success_criteria", [])),
1207
- deferred_items=tuple(all_deferred),
1208
1221
  decide_later_items=tuple(all_decide_later),
1209
1222
  assumptions=tuple(data.get("assumptions", [])),
1210
1223
  interview_id=interview_id,
@@ -1,7 +1,7 @@
1
1
  """PM Seed — immutable specification for product requirements.
2
2
 
3
3
  A PMSeed captures PM-level product requirements: goals, user stories,
4
- constraints, success criteria, and deferred items. It is produced by the
4
+ constraints, success criteria, and decide-later items. It is produced by the
5
5
  PM interview flow and can be serialized to YAML for handoff to a
6
6
  development interview via initial_context.
7
7
  """
@@ -10,12 +10,9 @@ from __future__ import annotations
10
10
 
11
11
  from dataclasses import dataclass, field
12
12
  from datetime import UTC, datetime
13
- from typing import TYPE_CHECKING
13
+ from typing import Any
14
14
  from uuid import uuid4
15
15
 
16
- if TYPE_CHECKING:
17
- from ouroboros.core.seed import Seed
18
-
19
16
 
20
17
  @dataclass(frozen=True, slots=True)
21
18
  class UserStory:
@@ -49,16 +46,18 @@ class PMSeed:
49
46
  user_stories: Captured user stories.
50
47
  constraints: Product constraints (budget, timeline, compliance, etc.).
51
48
  success_criteria: Measurable success criteria.
52
- deferred_items: Items explicitly deferred to later phases.
53
49
  assumptions: Assumptions made during the interview.
50
+ decide_later_items: Questions deferred or identified as premature.
54
51
  interview_id: Reference to the source PM interview.
55
52
  codebase_context: Shared codebase exploration context (brownfield).
56
53
  brownfield_repos: Registered brownfield repositories.
57
- seed: Optional reference to the generated dev Seed.
58
- deferred_decisions: Decisions deferred during PM interview
59
- (architectural, technical, or strategic choices postponed).
60
- referenced_repos: Repos referenced during PM interview for context.
61
54
  created_at: When this seed was generated.
55
+
56
+ Deprecated fields (kept for backward compatibility, merged on init):
57
+ deferred_items: Merged into decide_later_items.
58
+ deferred_decisions: Merged into decide_later_items.
59
+ seed: Preserved for legacy round-trip; not used by new code.
60
+ referenced_repos: Merged into brownfield_repos.
62
61
  """
63
62
 
64
63
  pm_id: str = field(default_factory=lambda: f"pm_seed_{uuid4().hex[:12]}")
@@ -67,45 +66,67 @@ class PMSeed:
67
66
  user_stories: tuple[UserStory, ...] = ()
68
67
  constraints: tuple[str, ...] = ()
69
68
  success_criteria: tuple[str, ...] = ()
70
- deferred_items: tuple[str, ...] = ()
71
69
  decide_later_items: tuple[str, ...] = ()
72
- """Original question text for items classified as decide-later.
70
+ """Items deferred or identified as premature during the PM interview.
73
71
 
74
- These are questions that were premature or unknowable during the PM
75
- interview. Stored as the original question text so they can be surfaced
76
- later when enough context exists to answer them.
72
+ Includes both feature-level deferrals and questions that were premature
73
+ or unknowable. Stored as the original question/item text so they can be
74
+ surfaced later when enough context exists to address them.
77
75
  """
78
76
  assumptions: tuple[str, ...] = ()
79
77
  interview_id: str = ""
80
78
  codebase_context: str = ""
81
79
  brownfield_repos: tuple[dict[str, str], ...] = ()
82
- seed: Seed | None = None
83
- """Optional reference to the generated dev Seed.
80
+ created_at: str = field(
81
+ default_factory=lambda: datetime.now(UTC).isoformat(),
82
+ )
84
83
 
85
- Populated after the dev interview produces a Seed from the PM
86
- requirements. None while in the PM-only phase.
87
- """
84
+ # ── Deprecated fields (backward compat, merged via __post_init__) ──
85
+ deferred_items: tuple[str, ...] = ()
88
86
  deferred_decisions: tuple[str, ...] = ()
89
- """Decisions deferred during the PM interview.
87
+ seed: Any = ""
88
+ """Legacy dev seed reference. Accepts str, dict, or Seed-like objects.
90
89
 
91
- These are architectural, technical, or strategic decisions that the PM
92
- chose to postpone. Distinct from decide_later_items (which are questions
93
- the classifier auto-deferred) and deferred_items (feature-level deferrals).
90
+ Preserved on round-trip: if the value has a ``to_dict()`` method it is
91
+ serialized via that; dicts and strings are passed through as-is.
94
92
  """
95
93
  referenced_repos: tuple[dict[str, str], ...] = ()
96
- """Repos referenced during the PM interview for brownfield context.
97
94
 
98
- Each entry is a dict with keys: path, name, desc. This captures which
99
- repositories were consulted during codebase exploration, providing
100
- traceability for the PM requirements.
101
- """
102
- created_at: str = field(
103
- default_factory=lambda: datetime.now(UTC).isoformat(),
104
- )
95
+ def __post_init__(self) -> None:
96
+ """Merge deprecated fields into their canonical counterparts."""
97
+ # Merge deferred_items and deferred_decisions → decide_later_items
98
+ if self.deferred_items or self.deferred_decisions:
99
+ combined = list(self.decide_later_items)
100
+ for item in self.deferred_items:
101
+ if item not in combined:
102
+ combined.append(item)
103
+ for item in self.deferred_decisions:
104
+ if item not in combined:
105
+ combined.append(item)
106
+ object.__setattr__(self, "decide_later_items", tuple(combined))
107
+ object.__setattr__(self, "deferred_items", ())
108
+ object.__setattr__(self, "deferred_decisions", ())
109
+
110
+ # Merge referenced_repos → brownfield_repos (additive, not replacement)
111
+ if self.referenced_repos:
112
+ if self.brownfield_repos:
113
+ merged = list(self.brownfield_repos)
114
+ existing_paths = {r.get("path") for r in merged}
115
+ for r in self.referenced_repos:
116
+ if r.get("path") not in existing_paths:
117
+ merged.append(r)
118
+ object.__setattr__(self, "brownfield_repos", tuple(merged))
119
+ else:
120
+ object.__setattr__(self, "brownfield_repos", self.referenced_repos)
121
+ object.__setattr__(self, "referenced_repos", ())
105
122
 
106
123
  def to_dict(self) -> dict:
107
- """Convert to a plain dictionary for YAML serialization."""
108
- return {
124
+ """Convert to a plain dictionary for YAML serialization.
125
+
126
+ Preserves legacy ``seed`` field when non-empty so that older
127
+ PM seed artifacts survive a load/save round-trip without data loss.
128
+ """
129
+ d: dict = {
109
130
  "pm_id": self.pm_id,
110
131
  "product_name": self.product_name,
111
132
  "goal": self.goal,
@@ -115,23 +136,32 @@ class PMSeed:
115
136
  ],
116
137
  "constraints": list(self.constraints),
117
138
  "success_criteria": list(self.success_criteria),
118
- "deferred_items": list(self.deferred_items),
119
139
  "decide_later_items": list(self.decide_later_items),
120
140
  "assumptions": list(self.assumptions),
121
141
  "interview_id": self.interview_id,
122
142
  "codebase_context": self.codebase_context,
123
143
  "brownfield_repos": [dict(r) for r in self.brownfield_repos],
124
- "seed": self.seed.to_dict() if self.seed is not None else None,
125
- "deferred_decisions": list(self.deferred_decisions),
126
- "referenced_repos": [dict(r) for r in self.referenced_repos],
127
144
  "created_at": self.created_at,
128
145
  }
146
+ # Preserve legacy seed for round-trip safety.
147
+ # Handles Seed objects (via to_dict()), raw dicts, and strings.
148
+ # Explicit None check: falsey-but-present values ({}, 0) are preserved.
149
+ if self.seed is not None and self.seed != "":
150
+ if hasattr(self.seed, "to_dict"):
151
+ d["seed"] = self.seed.to_dict()
152
+ else:
153
+ d["seed"] = self.seed
154
+ return d
129
155
 
130
156
  @classmethod
131
157
  def from_dict(cls, data: dict) -> PMSeed:
132
- """Create a PMSeed from a dictionary (e.g., loaded from YAML)."""
133
- from ouroboros.core.seed import Seed
158
+ """Create a PMSeed from a dictionary (e.g., loaded from YAML).
134
159
 
160
+ Handles backward compatibility: legacy fields ``deferred_items``,
161
+ ``deferred_decisions``, ``seed``, and ``referenced_repos`` are
162
+ accepted and migrated to their canonical counterparts via
163
+ ``__post_init__``.
164
+ """
135
165
  stories = tuple(
136
166
  UserStory(
137
167
  persona=s.get("persona", ""),
@@ -141,9 +171,29 @@ class PMSeed:
141
171
  for s in data.get("user_stories", [])
142
172
  )
143
173
 
144
- # Deserialize seed if present
145
- seed_data = data.get("seed")
146
- seed = Seed.from_dict(seed_data) if seed_data is not None else None
174
+ # Backward compat: merge legacy deferred_items / deferred_decisions
175
+ # into decide_later_items (canonical field since v0.25).
176
+ decide_later = list(data.get("decide_later_items", []))
177
+ for key in ("deferred_items", "deferred_decisions"):
178
+ for item in data.get(key, []):
179
+ if item not in decide_later:
180
+ decide_later.append(item)
181
+
182
+ # Backward compat: merge referenced_repos into brownfield_repos (additive)
183
+ brownfield_raw = list(data.get("brownfield_repos", []))
184
+ for r in data.get("referenced_repos", []):
185
+ if r not in brownfield_raw:
186
+ brownfield_raw.append(r)
187
+
188
+ # Rehydrate legacy seed: dict → Seed object if possible
189
+ seed_raw = data.get("seed", "")
190
+ if isinstance(seed_raw, dict):
191
+ try:
192
+ from ouroboros.core.seed import Seed as DevSeed
193
+
194
+ seed_raw = DevSeed.from_dict(seed_raw)
195
+ except Exception:
196
+ pass # Preserve as raw dict if Seed import/parse fails
147
197
 
148
198
  return cls(
149
199
  pm_id=data.get("pm_id", ""),
@@ -152,16 +202,13 @@ class PMSeed:
152
202
  user_stories=stories,
153
203
  constraints=tuple(data.get("constraints", [])),
154
204
  success_criteria=tuple(data.get("success_criteria", [])),
155
- deferred_items=tuple(data.get("deferred_items", [])),
156
- decide_later_items=tuple(data.get("decide_later_items", [])),
205
+ decide_later_items=tuple(decide_later),
157
206
  assumptions=tuple(data.get("assumptions", [])),
158
207
  interview_id=data.get("interview_id", ""),
159
208
  codebase_context=data.get("codebase_context", ""),
160
- brownfield_repos=tuple(dict(r) for r in data.get("brownfield_repos", [])),
161
- seed=seed,
162
- deferred_decisions=tuple(data.get("deferred_decisions", [])),
163
- referenced_repos=tuple(dict(r) for r in data.get("referenced_repos", [])),
209
+ brownfield_repos=tuple(dict(r) for r in brownfield_raw),
164
210
  created_at=data.get("created_at", ""),
211
+ seed=seed_raw,
165
212
  )
166
213
 
167
214
  def to_initial_context(self) -> str:
@@ -355,9 +355,15 @@ def _save_cli_pm_meta(session_id: str, engine: Any) -> None:
355
355
  "original": engine._reframe_map[reframed],
356
356
  }
357
357
 
358
+ # Collapse deferred_items into decide_later_items (canonical schema)
359
+ combined_decide_later = list(engine.decide_later_items)
360
+ for item in engine.deferred_items:
361
+ if item not in combined_decide_later:
362
+ combined_decide_later.append(item)
363
+
358
364
  meta = {
359
- "deferred_items": list(engine.deferred_items),
360
- "decide_later_items": list(engine.decide_later_items),
365
+ "deferred_items": [], # Deprecated: merged into decide_later_items
366
+ "decide_later_items": combined_decide_later,
361
367
  "codebase_context": engine.codebase_context,
362
368
  "pending_reframe": pending_reframe,
363
369
  "cwd": "",
@@ -589,8 +595,8 @@ async def _run_pm_interview(
589
595
  session_id=state.interview_id,
590
596
  completion=completion,
591
597
  stored_ambiguity_score=state.ambiguity_score,
592
- deferred_count=len(engine.deferred_items),
593
- decide_later_count=len(engine.decide_later_items),
598
+ deferred_count=0,
599
+ decide_later_count=len(engine.deferred_items) + len(engine.decide_later_items),
594
600
  decide_later_summary=decide_later_summary,
595
601
  )
596
602
  console.print(f"\n[bold green]{summary_text}[/]\n")
@@ -660,8 +666,8 @@ async def _run_pm_interview(
660
666
  session_id=state.interview_id,
661
667
  completion=completion,
662
668
  stored_ambiguity_score=state.ambiguity_score,
663
- deferred_count=len(engine.deferred_items),
664
- decide_later_count=len(engine.decide_later_items),
669
+ deferred_count=0,
670
+ decide_later_count=len(engine.deferred_items) + len(engine.decide_later_items),
665
671
  decide_later_summary=decide_later_summary,
666
672
  )
667
673
  console.print(f"\n[bold green]{summary_text}[/]\n")
@@ -89,9 +89,16 @@ def _save_pm_meta(
89
89
  if engine is not None:
90
90
  pending_reframe = engine.get_pending_reframe()
91
91
 
92
+ # Collapse deferred_items into decide_later_items so the persisted
93
+ # metadata uses the same canonical schema as PMSeed.
94
+ combined_decide_later = list(engine.decide_later_items)
95
+ for item in engine.deferred_items:
96
+ if item not in combined_decide_later:
97
+ combined_decide_later.append(item)
98
+
92
99
  meta: dict[str, Any] = {
93
- "deferred_items": list(engine.deferred_items),
94
- "decide_later_items": list(engine.decide_later_items),
100
+ "deferred_items": [], # Deprecated: merged into decide_later_items
101
+ "decide_later_items": combined_decide_later,
95
102
  "codebase_context": engine.codebase_context,
96
103
  "pending_reframe": pending_reframe,
97
104
  "cwd": cwd,
@@ -874,8 +881,9 @@ class PMInterviewHandler:
874
881
  "pending_reframe": pending_reframe,
875
882
  "new_deferred": [],
876
883
  "new_decide_later": [],
877
- "deferred_count": len(engine.deferred_items),
878
- "decide_later_count": len(engine.decide_later_items),
884
+ "deferred_count": 0,
885
+ "decide_later_count": len(engine.deferred_items)
886
+ + len(engine.decide_later_items),
879
887
  },
880
888
  )
881
889
  )
@@ -1028,8 +1036,8 @@ class PMInterviewHandler:
1028
1036
  session_id=session_id,
1029
1037
  completion=completion,
1030
1038
  stored_ambiguity_score=getattr(state, "ambiguity_score", None),
1031
- deferred_count=len(engine.deferred_items),
1032
- decide_later_count=len(engine.decide_later_items),
1039
+ deferred_count=0,
1040
+ decide_later_count=len(engine.deferred_items) + len(engine.decide_later_items),
1033
1041
  decide_later_summary=decide_later_summary,
1034
1042
  )
1035
1043
  summary_text += f"\n\nPM document: {pm_path}\nSeed: {seed_path}"
@@ -1042,8 +1050,8 @@ class PMInterviewHandler:
1042
1050
  "deferred_this_round": [],
1043
1051
  "decide_later_this_round": [],
1044
1052
  **completion,
1045
- "deferred_count": len(engine.deferred_items),
1046
- "decide_later_count": len(engine.decide_later_items),
1053
+ "deferred_count": 0,
1054
+ "decide_later_count": len(engine.deferred_items) + len(engine.decide_later_items),
1047
1055
  "seed_path": str(seed_path),
1048
1056
  "pm_path": str(pm_path),
1049
1057
  }
@@ -1273,7 +1281,6 @@ class PMInterviewHandler:
1273
1281
  f"PM document: {pm_path}\n\n"
1274
1282
  "This PM seed is a handoff artifact for the dev interview, "
1275
1283
  "not the runnable Seed.\n"
1276
- f"Deferred items: {len(seed.deferred_items)}\n"
1277
1284
  f"Decide-later items: {len(seed.decide_later_items)}\n"
1278
1285
  f"Next: {next_step}"
1279
1286
  ),
@@ -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)