ouroboros-ai 0.26.6.dev1__tar.gz → 0.26.7.dev1__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 (576) hide show
  1. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.claude-plugin/marketplace.json +1 -1
  2. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.claude-plugin/plugin.json +1 -1
  3. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/PKG-INFO +1 -1
  4. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/setup/SKILL.md +1 -1
  5. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/_version.py +2 -2
  6. ouroboros_ai-0.26.7.dev1/src/ouroboros/core/json_utils.py +93 -0
  7. ouroboros_ai-0.26.7.dev1/src/ouroboros/evaluation/json_utils.py +5 -0
  8. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/events.py +39 -0
  9. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/runner.py +67 -0
  10. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/claude_code_adapter.py +123 -7
  11. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/app.py +6 -0
  12. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/events.py +8 -0
  13. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_json_utils.py +48 -0
  14. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/providers/test_claude_code_adapter.py +136 -2
  15. ouroboros_ai-0.26.6.dev1/src/ouroboros/evaluation/json_utils.py +0 -79
  16. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.claude/settings.json +0 -0
  17. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.claude-plugin/.mcp.json +0 -0
  18. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.env.example +0 -0
  19. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  20. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  21. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  22. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  23. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/workflows/dev-publish.yml +0 -0
  24. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/workflows/lint.yml +0 -0
  25. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/workflows/release.yml +0 -0
  26. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.github/workflows/test.yml +0 -0
  27. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.gitignore +0 -0
  28. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.mcp.json +0 -0
  29. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.ouroboros/mechanical.toml +0 -0
  30. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.pre-commit-config.yaml +0 -0
  31. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/.python-version +0 -0
  32. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/CHANGELOG.md +0 -0
  33. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/CLAUDE.md +0 -0
  34. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/CODE_OF_CONDUCT.md +0 -0
  35. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/CONTRIBUTING.md +0 -0
  36. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/HANDOFF.md +0 -0
  37. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/LICENSE +0 -0
  38. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/README.ko.md +0 -0
  39. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/README.md +0 -0
  40. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/SECURITY.md +0 -0
  41. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/UNINSTALL.md +0 -0
  42. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/cancel.md +0 -0
  43. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/evaluate.md +0 -0
  44. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/evolve.md +0 -0
  45. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/help.md +0 -0
  46. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/interview.md +0 -0
  47. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/ralph.md +0 -0
  48. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/run.md +0 -0
  49. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/seed.md +0 -0
  50. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/setup.md +0 -0
  51. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/status.md +0 -0
  52. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/tutorial.md +0 -0
  53. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/unstuck.md +0 -0
  54. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/commands/welcome.md +0 -0
  55. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/.gitignore +0 -0
  56. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/Cargo.lock +0 -0
  57. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/Cargo.toml +0 -0
  58. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/README.md +0 -0
  59. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/db.rs +0 -0
  60. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/main.rs +0 -0
  61. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/mock.rs +0 -0
  62. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/state.rs +0 -0
  63. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
  64. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/views/execution.rs +0 -0
  65. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
  66. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/views/logs.rs +0 -0
  67. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/views/mod.rs +0 -0
  68. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
  69. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/README.md +0 -0
  70. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/api/README.md +0 -0
  71. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/api/core.md +0 -0
  72. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/api/mcp.md +0 -0
  73. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/architecture.md +0 -0
  74. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/cli-reference.md +0 -0
  75. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/config-reference.md +0 -0
  76. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/contributing/architecture-overview.md +0 -0
  77. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/contributing/findings-registry.md +0 -0
  78. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/contributing/issue-quality-policy.md +0 -0
  79. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/contributing/key-patterns.md +0 -0
  80. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/contributing/testing-guide.md +0 -0
  81. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/examples/mcp-config.yaml +0 -0
  82. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/getting-started.md +0 -0
  83. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/guides/evaluation-pipeline.md +0 -0
  84. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/guides/evolution-loop.md +0 -0
  85. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
  86. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/guides/seed-authoring.md +0 -0
  87. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/guides/tui-usage.md +0 -0
  88. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/images/PLACEHOLDER_README.md +0 -0
  89. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/images/ouroboros.png +0 -0
  90. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/platform-support.md +0 -0
  91. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/runtime-capability-matrix.md +0 -0
  92. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/runtime-guides/claude-code.md +0 -0
  93. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/docs/runtime-guides/codex.md +0 -0
  94. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/coordinator_test_seed.yaml +0 -0
  95. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/dummy_seed.yaml +0 -0
  96. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/parallel_subac_test_seed.yaml +0 -0
  97. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/subac_test_seed.yaml +0 -0
  98. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/task_manager/README.md +0 -0
  99. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/task_manager/__init__.py +0 -0
  100. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/task_manager/__main__.py +0 -0
  101. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/task_manager/cli.py +0 -0
  102. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/task_manager/models.py +0 -0
  103. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/task_manager/storage.py +0 -0
  104. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/examples/test_display.py +0 -0
  105. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/hooks/hooks.json +0 -0
  106. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/llms-full.txt +0 -0
  107. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/llms.txt +0 -0
  108. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/project-context.md +0 -0
  109. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/pyproject.toml +0 -0
  110. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/drift-monitor.py +0 -0
  111. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/install.sh +0 -0
  112. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/keyword-detector.py +0 -0
  113. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/mcp-serve.sh +0 -0
  114. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/ralph-rewind.py +0 -0
  115. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/ralph.py +0 -0
  116. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/ralph.sh +0 -0
  117. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/session-start.py +0 -0
  118. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/sync-plugin-version.py +0 -0
  119. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/scripts/version-check.py +0 -0
  120. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/brownfield/SKILL.md +0 -0
  121. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/cancel/SKILL.md +0 -0
  122. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/evaluate/SKILL.md +0 -0
  123. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/evolve/SKILL.md +0 -0
  124. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/help/SKILL.md +0 -0
  125. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/interview/SKILL.md +0 -0
  126. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/pm/SKILL.md +0 -0
  127. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/qa/SKILL.md +0 -0
  128. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/ralph/SKILL.md +0 -0
  129. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/run/SKILL.md +0 -0
  130. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/seed/SKILL.md +0 -0
  131. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/status/SKILL.md +0 -0
  132. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/tutorial/SKILL.md +0 -0
  133. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/unstuck/SKILL.md +0 -0
  134. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/update/SKILL.md +0 -0
  135. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/skills/welcome/SKILL.md +0 -0
  136. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/__init__.py +0 -0
  137. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/__main__.py +0 -0
  138. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/__init__.py +0 -0
  139. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/advocate.md +0 -0
  140. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/analysis-agent.md +0 -0
  141. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/architect.md +0 -0
  142. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/breadth-keeper.md +0 -0
  143. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/code-executor.md +0 -0
  144. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/codebase-explorer.md +0 -0
  145. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/consensus-reviewer.md +0 -0
  146. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/contrarian.md +0 -0
  147. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/evaluator.md +0 -0
  148. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/hacker.md +0 -0
  149. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/judge.md +0 -0
  150. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/loader.py +0 -0
  151. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/ontologist.md +0 -0
  152. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/ontology-analyst.md +0 -0
  153. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/qa-judge.md +0 -0
  154. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/research-agent.md +0 -0
  155. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/researcher.md +0 -0
  156. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/seed-architect.md +0 -0
  157. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/seed-closer.md +0 -0
  158. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/semantic-evaluator.md +0 -0
  159. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/simplifier.md +0 -0
  160. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/agents/socratic-interviewer.md +0 -0
  161. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/__init__.py +0 -0
  162. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/ambiguity.py +0 -0
  163. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/brownfield.py +0 -0
  164. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/explore.py +0 -0
  165. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/interview.py +0 -0
  166. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/pm_completion.py +0 -0
  167. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/pm_document.py +0 -0
  168. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/pm_interview.py +0 -0
  169. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/pm_seed.py +0 -0
  170. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/question_classifier.py +0 -0
  171. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/bigbang/seed_generator.py +0 -0
  172. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/__init__.py +0 -0
  173. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/__init__.py +0 -0
  174. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/cancel.py +0 -0
  175. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/config.py +0 -0
  176. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/init.py +0 -0
  177. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/mcp.py +0 -0
  178. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/pm.py +0 -0
  179. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/run.py +0 -0
  180. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/setup.py +0 -0
  181. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/status.py +0 -0
  182. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/tui.py +0 -0
  183. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/commands/uninstall.py +0 -0
  184. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/formatters/__init__.py +0 -0
  185. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/formatters/panels.py +0 -0
  186. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/formatters/progress.py +0 -0
  187. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/formatters/prompting.py +0 -0
  188. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/formatters/tables.py +0 -0
  189. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
  190. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/cli/main.py +0 -0
  191. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/codex/__init__.py +0 -0
  192. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/codex/artifacts.py +0 -0
  193. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/codex/ouroboros.md +0 -0
  194. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/codex_permissions.py +0 -0
  195. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/config/__init__.py +0 -0
  196. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/config/loader.py +0 -0
  197. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/config/models.py +0 -0
  198. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/__init__.py +0 -0
  199. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/ac_tree.py +0 -0
  200. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/context.py +0 -0
  201. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/errors.py +0 -0
  202. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/file_lock.py +0 -0
  203. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/git_workflow.py +0 -0
  204. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/initial_context.py +0 -0
  205. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/lineage.py +0 -0
  206. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/ontology_aspect.py +0 -0
  207. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/ontology_questions.py +0 -0
  208. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/project_paths.py +0 -0
  209. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/security.py +0 -0
  210. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/seed.py +0 -0
  211. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/text.py +0 -0
  212. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/types.py +0 -0
  213. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/core/worktree.py +0 -0
  214. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/__init__.py +0 -0
  215. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/artifact_collector.py +0 -0
  216. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/consensus.py +0 -0
  217. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/languages.py +0 -0
  218. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/mechanical.py +0 -0
  219. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/models.py +0 -0
  220. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/pipeline.py +0 -0
  221. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/semantic.py +0 -0
  222. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/trigger.py +0 -0
  223. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
  224. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/__init__.py +0 -0
  225. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/base.py +0 -0
  226. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/decomposition.py +0 -0
  227. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/evaluation.py +0 -0
  228. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/interview.py +0 -0
  229. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/lineage.py +0 -0
  230. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/events/ontology.py +0 -0
  231. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/__init__.py +0 -0
  232. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/convergence.py +0 -0
  233. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/loop.py +0 -0
  234. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/projector.py +0 -0
  235. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/reflect.py +0 -0
  236. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/regression.py +0 -0
  237. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/evolution/wonder.py +0 -0
  238. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/execution/__init__.py +0 -0
  239. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/execution/atomicity.py +0 -0
  240. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/execution/decomposition.py +0 -0
  241. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/execution/double_diamond.py +0 -0
  242. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/execution/subagent.py +0 -0
  243. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/__init__.py +0 -0
  244. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/client/__init__.py +0 -0
  245. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/client/adapter.py +0 -0
  246. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/client/manager.py +0 -0
  247. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/client/protocol.py +0 -0
  248. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/errors.py +0 -0
  249. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/job_manager.py +0 -0
  250. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/resources/__init__.py +0 -0
  251. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/resources/handlers.py +0 -0
  252. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/server/__init__.py +0 -0
  253. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/server/adapter.py +0 -0
  254. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/server/protocol.py +0 -0
  255. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/server/security.py +0 -0
  256. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/__init__.py +0 -0
  257. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
  258. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
  259. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/dashboard.py +0 -0
  260. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/definitions.py +0 -0
  261. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
  262. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
  263. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
  264. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
  265. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/pm_handler.py +0 -0
  266. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/qa.py +0 -0
  267. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
  268. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/tools/registry.py +0 -0
  269. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/mcp/types.py +0 -0
  270. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/observability/__init__.py +0 -0
  271. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/observability/drift.py +0 -0
  272. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/observability/logging.py +0 -0
  273. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/observability/retrospective.py +0 -0
  274. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/__init__.py +0 -0
  275. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/adapter.py +0 -0
  276. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
  277. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
  278. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/coordinator.py +0 -0
  279. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
  280. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
  281. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
  282. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/heartbeat.py +0 -0
  283. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/level_context.py +0 -0
  284. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/mcp_config.py +0 -0
  285. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
  286. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
  287. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
  288. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
  289. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
  290. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/session.py +0 -0
  291. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/orchestrator/workflow_state.py +0 -0
  292. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/__init__.py +0 -0
  293. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/brownfield.py +0 -0
  294. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/checkpoint.py +0 -0
  295. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/event_store.py +0 -0
  296. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/migrations/__init__.py +0 -0
  297. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/migrations/runner.py +0 -0
  298. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
  299. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
  300. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/schema.py +0 -0
  301. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/persistence/uow.py +0 -0
  302. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/__init__.py +0 -0
  303. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/agents/__init__.py +0 -0
  304. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/agents/pool.py +0 -0
  305. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/agents/registry.py +0 -0
  306. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
  307. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/orchestration/router.py +0 -0
  308. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
  309. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/skills/__init__.py +0 -0
  310. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/skills/docs.py +0 -0
  311. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/skills/executor.py +0 -0
  312. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/skills/keywords.py +0 -0
  313. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/plugin/skills/registry.py +0 -0
  314. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/pm/__init__.py +0 -0
  315. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/pm/handoff.py +0 -0
  316. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/pm/renderer.py +0 -0
  317. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/__init__.py +0 -0
  318. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/anthropic_adapter.py +0 -0
  319. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/base.py +0 -0
  320. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/codex_cli_adapter.py +0 -0
  321. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/codex_cli_stream.py +0 -0
  322. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/factory.py +0 -0
  323. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/providers/litellm_adapter.py +0 -0
  324. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/py.typed +0 -0
  325. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/resilience/__init__.py +0 -0
  326. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/resilience/lateral.py +0 -0
  327. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/resilience/stagnation.py +0 -0
  328. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/routing/__init__.py +0 -0
  329. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/routing/complexity.py +0 -0
  330. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/routing/downgrade.py +0 -0
  331. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/routing/escalation.py +0 -0
  332. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/routing/router.py +0 -0
  333. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/routing/tiers.py +0 -0
  334. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/secondary/__init__.py +0 -0
  335. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/secondary/scheduler.py +0 -0
  336. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/secondary/todo_registry.py +0 -0
  337. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/strategies/__init__.py +0 -0
  338. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/strategies/devil_advocate.py +0 -0
  339. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/__init__.py +0 -0
  340. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/components/__init__.py +0 -0
  341. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/components/agents_panel.py +0 -0
  342. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/components/event_log.py +0 -0
  343. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/components/progress.py +0 -0
  344. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/components/token_tracker.py +0 -0
  345. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/__init__.py +0 -0
  346. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
  347. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/dashboard.py +0 -0
  348. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
  349. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
  350. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/debug.py +0 -0
  351. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/execution.py +0 -0
  352. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
  353. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
  354. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
  355. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/logs.py +0 -0
  356. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/screens/session_selector.py +0 -0
  357. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/__init__.py +0 -0
  358. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
  359. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
  360. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
  361. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
  362. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
  363. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
  364. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
  365. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
  366. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/verification/__init__.py +0 -0
  367. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/verification/extractor.py +0 -0
  368. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/verification/models.py +0 -0
  369. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/src/ouroboros/verification/verifier.py +0 -0
  370. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/__init__.py +0 -0
  371. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/conftest.py +0 -0
  372. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/e2e/__init__.py +0 -0
  373. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/e2e/conftest.py +0 -0
  374. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/e2e/test_cli_commands.py +0 -0
  375. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/e2e/test_full_workflow.py +0 -0
  376. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/e2e/test_session_persistence.py +0 -0
  377. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/fixtures/test_atomicity_seed.yml +0 -0
  378. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/__init__.py +0 -0
  379. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/conftest.py +0 -0
  380. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/mcp/__init__.py +0 -0
  381. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/mcp/conftest.py +0 -0
  382. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/mcp/test_client_adapter.py +0 -0
  383. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/mcp/test_client_manager.py +0 -0
  384. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/mcp/test_server_adapter.py +0 -0
  385. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/plugin/test_orchestration.py +0 -0
  386. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
  387. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/test_codex_skill_fallback.py +0 -0
  388. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/test_codex_skill_smoke.py +0 -0
  389. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/integration/test_entry_point.py +0 -0
  390. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/__init__.py +0 -0
  391. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/agents/__init__.py +0 -0
  392. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/agents/test_loader.py +0 -0
  393. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/__init__.py +0 -0
  394. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_ambiguity.py +0 -0
  395. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_brownfield.py +0 -0
  396. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_classifier_context.py +0 -0
  397. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_decide_later_items.py +0 -0
  398. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_explore.py +0 -0
  399. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_interview.py +0 -0
  400. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_completion.py +0 -0
  401. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
  402. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
  403. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_interview.py +0 -0
  404. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
  405. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
  406. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
  407. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_question_classifier.py +0 -0
  408. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/bigbang/test_seed_generator.py +0 -0
  409. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/__init__.py +0 -0
  410. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/__init__.py +0 -0
  411. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/test_console.py +0 -0
  412. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/test_panels.py +0 -0
  413. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/test_progress.py +0 -0
  414. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/test_prompting.py +0 -0
  415. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/test_tables.py +0 -0
  416. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
  417. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_cancel.py +0 -0
  418. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_config.py +0 -0
  419. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_init_pm_seed_detection.py +0 -0
  420. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_init_runtime.py +0 -0
  421. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_main.py +0 -0
  422. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
  423. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
  424. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm.py +0 -0
  425. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_brownfield.py +0 -0
  426. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_completion.py +0 -0
  427. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_interactive_logging.py +0 -0
  428. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
  429. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_overwrite.py +0 -0
  430. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_runtime_adapter.py +0 -0
  431. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_pm_select_repos.py +0 -0
  432. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_run_qa.py +0 -0
  433. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_setup.py +0 -0
  434. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/cli/test_uninstall.py +0 -0
  435. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/config/__init__.py +0 -0
  436. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/config/test_loader.py +0 -0
  437. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/config/test_models.py +0 -0
  438. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/__init__.py +0 -0
  439. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_ac_tree.py +0 -0
  440. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_context.py +0 -0
  441. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_errors.py +0 -0
  442. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_git_workflow.py +0 -0
  443. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_initial_context.py +0 -0
  444. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_lineage.py +0 -0
  445. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_ontology_aspect.py +0 -0
  446. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_ontology_questions.py +0 -0
  447. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_security.py +0 -0
  448. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_seed.py +0 -0
  449. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_types.py +0 -0
  450. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/core/test_worktree.py +0 -0
  451. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/__init__.py +0 -0
  452. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_consensus.py +0 -0
  453. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_languages.py +0 -0
  454. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_mechanical.py +0 -0
  455. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_models.py +0 -0
  456. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_semantic.py +0 -0
  457. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_trigger.py +0 -0
  458. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
  459. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/events/__init__.py +0 -0
  460. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/events/test_base.py +0 -0
  461. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/events/test_decomposition_events.py +0 -0
  462. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/evolution/test_wonder_scope.py +0 -0
  463. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/execution/__init__.py +0 -0
  464. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/execution/test_atomicity.py +0 -0
  465. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/execution/test_decomposition.py +0 -0
  466. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/execution/test_double_diamond.py +0 -0
  467. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/execution/test_subagent_isolation.py +0 -0
  468. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/__init__.py +0 -0
  469. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/client/__init__.py +0 -0
  470. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/client/test_adapter.py +0 -0
  471. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/client/test_manager.py +0 -0
  472. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/conftest.py +0 -0
  473. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/server/__init__.py +0 -0
  474. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/server/test_adapter.py +0 -0
  475. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/server/test_security.py +0 -0
  476. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/test_errors.py +0 -0
  477. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/test_job_manager.py +0 -0
  478. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/test_types.py +0 -0
  479. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/__init__.py +0 -0
  480. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/conftest.py +0 -0
  481. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
  482. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_definitions.py +0 -0
  483. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_pm_handler.py +0 -0
  484. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_pm_handler_generate.py +0 -0
  485. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
  486. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
  487. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_qa_parser.py +0 -0
  488. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/mcp/tools/test_registry.py +0 -0
  489. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/observability/__init__.py +0 -0
  490. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/observability/test_drift.py +0 -0
  491. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/observability/test_logging.py +0 -0
  492. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/observability/test_retrospective.py +0 -0
  493. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/__init__.py +0 -0
  494. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_adapter.py +0 -0
  495. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
  496. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
  497. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
  498. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_coordinator.py +0 -0
  499. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
  500. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_events.py +0 -0
  501. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
  502. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
  503. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
  504. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_level_context.py +0 -0
  505. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_mcp_config.py +0 -0
  506. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
  507. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
  508. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
  509. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_runner.py +0 -0
  510. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
  511. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
  512. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
  513. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_session.py +0 -0
  514. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/orchestrator/test_workflow_state.py +0 -0
  515. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/persistence/__init__.py +0 -0
  516. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/persistence/test_brownfield_store.py +0 -0
  517. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/persistence/test_checkpoint.py +0 -0
  518. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/persistence/test_event_store.py +0 -0
  519. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/persistence/test_schema.py +0 -0
  520. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/persistence/test_uow.py +0 -0
  521. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/__init__.py +0 -0
  522. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/agents/__init__.py +0 -0
  523. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/agents/test_registry.py +0 -0
  524. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/orchestration/__init__.py +0 -0
  525. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
  526. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/skills/__init__.py +0 -0
  527. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/skills/test_keywords.py +0 -0
  528. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/plugin/skills/test_registry.py +0 -0
  529. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/pm/__init__.py +0 -0
  530. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/pm/test_renderer.py +0 -0
  531. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/providers/__init__.py +0 -0
  532. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/providers/test_base.py +0 -0
  533. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/providers/test_codex_cli_adapter.py +0 -0
  534. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/providers/test_factory.py +0 -0
  535. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/providers/test_litellm_adapter.py +0 -0
  536. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/resilience/__init__.py +0 -0
  537. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/resilience/test_lateral.py +0 -0
  538. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/resilience/test_stagnation.py +0 -0
  539. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/routing/__init__.py +0 -0
  540. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/routing/test_complexity.py +0 -0
  541. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/routing/test_downgrade.py +0 -0
  542. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/routing/test_escalation.py +0 -0
  543. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/routing/test_router.py +0 -0
  544. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/routing/test_tiers.py +0 -0
  545. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/scripts/test_keyword_detector.py +0 -0
  546. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/scripts/test_version_check.py +0 -0
  547. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/secondary/__init__.py +0 -0
  548. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/secondary/test_scheduler.py +0 -0
  549. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/secondary/test_todo_registry.py +0 -0
  550. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_artifact_collector.py +0 -0
  551. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_codex_artifacts.py +0 -0
  552. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_convergence.py +0 -0
  553. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_dashboard.py +0 -0
  554. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_dependencies_configured.py +0 -0
  555. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_evolve_rewind.py +0 -0
  556. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_evolve_step.py +0 -0
  557. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_graceful_shutdown.py +0 -0
  558. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_main_entry_point.py +0 -0
  559. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_module_structure.py +0 -0
  560. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_project_initialization.py +0 -0
  561. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_projector_rewind.py +0 -0
  562. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_ralph_parser.py +0 -0
  563. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_ralph_rewind.py +0 -0
  564. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_regression.py +0 -0
  565. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_tooling_configuration.py +0 -0
  566. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/test_verification.py +0 -0
  567. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/__init__.py +0 -0
  568. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_app.py +0 -0
  569. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_cancelled_display.py +0 -0
  570. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_events.py +0 -0
  571. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_lineage_viewer.py +0 -0
  572. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_screens.py +0 -0
  573. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_session_selector_replay.py +0 -0
  574. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tests/unit/tui/test_widgets.py +0 -0
  575. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/tools/sync_github_project.py +0 -0
  576. {ouroboros_ai-0.26.6.dev1 → ouroboros_ai-0.26.7.dev1}/uv.lock +0 -0
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "ouroboros",
12
12
  "description": "Transform vague ideas into validated seed specifications through Socratic questioning and ontological analysis",
13
- "version": "0.26.5",
13
+ "version": "0.26.6",
14
14
  "author": {
15
15
  "name": "Q00",
16
16
  "email": "jqyu.lee@gmail.com"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ouroboros",
3
- "version": "0.26.5",
3
+ "version": "0.26.6",
4
4
  "description": "Self-improving AI workflow system. Crystallize requirements before execution with Socratic interview, ambiguity scoring, and 3-stage evaluation.",
5
5
  "author": {
6
6
  "name": "Q00",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ouroboros-ai
3
- Version: 0.26.6.dev1
3
+ Version: 0.26.7.dev1
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
@@ -246,7 +246,7 @@ A backup will be created: CLAUDE.md.bak
246
246
  **If "Preview first", show:**
247
247
  ````markdown
248
248
  <!-- ooo:START -->
249
- <!-- ooo:VERSION:0.26.5 -->
249
+ <!-- ooo:VERSION:0.26.6 -->
250
250
  # Ouroboros — Specification-First AI Development
251
251
 
252
252
  > Before telling AI what to build, define what should be built.
@@ -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.6.dev1'
22
- __version_tuple__ = version_tuple = (0, 26, 6, 'dev1')
21
+ __version__ = version = '0.26.7.dev1'
22
+ __version_tuple__ = version_tuple = (0, 26, 7, 'dev1')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,93 @@
1
+ """Shared JSON extraction utilities for evaluation modules.
2
+
3
+ Provides a robust bracket-matching JSON extractor used by semantic,
4
+ consensus, and QA evaluation stages.
5
+ """
6
+
7
+ import json
8
+ import re
9
+
10
+
11
+ def extract_json_payload(text: str) -> str | None:
12
+ """Extract the first valid JSON object or array from text.
13
+
14
+ Tries each ``{`` or ``[`` position via bracket-depth counting and
15
+ validates with ``json.loads``. This handles LLM responses that
16
+ contain prose before the actual JSON payload.
17
+
18
+ Args:
19
+ text: Raw text potentially containing a JSON object or array
20
+
21
+ Returns:
22
+ Extracted JSON string, or None if no valid JSON is found
23
+ """
24
+ # Strip code fences first (```json ... ```)
25
+ fence_match = re.search(r"```(?:json)?\s*([\[{][\s\S]*?[}\]])\s*```", text)
26
+ if fence_match:
27
+ text = fence_match.group(1)
28
+
29
+ pos = 0
30
+ while True:
31
+ # Find the next { or [ opener
32
+ obj_start = text.find("{", pos)
33
+ arr_start = text.find("[", pos)
34
+
35
+ if obj_start == -1 and arr_start == -1:
36
+ return None
37
+
38
+ # Pick whichever comes first
39
+ if obj_start == -1:
40
+ start = arr_start
41
+ elif arr_start == -1:
42
+ start = obj_start
43
+ else:
44
+ start = min(obj_start, arr_start)
45
+
46
+ candidate = _bracket_extract(text, start)
47
+ if candidate is not None:
48
+ try:
49
+ json.loads(candidate)
50
+ return candidate
51
+ except (json.JSONDecodeError, ValueError):
52
+ pass
53
+
54
+ pos = start + 1
55
+
56
+
57
+ def _bracket_extract(text: str, start: int) -> str | None:
58
+ """Extract a bracket-balanced substring starting at *start*.
59
+
60
+ Supports both ``{}`` (objects) and ``[]`` (arrays). Returns the
61
+ substring ``text[start:end+1]`` where *end* is the position of
62
+ the matching closer, or ``None`` if brackets never balance.
63
+ """
64
+ open_char = text[start]
65
+ close_char = "}" if open_char == "{" else "]"
66
+ depth = 0
67
+ in_string = False
68
+ escape_next = False
69
+
70
+ for i, char in enumerate(text[start:], start=start):
71
+ if escape_next:
72
+ escape_next = False
73
+ continue
74
+
75
+ if char == "\\":
76
+ escape_next = True
77
+ continue
78
+
79
+ if char == '"' and not escape_next:
80
+ in_string = not in_string
81
+ continue
82
+
83
+ if in_string:
84
+ continue
85
+
86
+ if char == open_char:
87
+ depth += 1
88
+ elif char == close_char:
89
+ depth -= 1
90
+ if depth == 0:
91
+ return text[start : i + 1]
92
+
93
+ return None
@@ -0,0 +1,5 @@
1
+ """Backwards-compatible re-export. Canonical location: ouroboros.core.json_utils."""
2
+
3
+ from ouroboros.core.json_utils import extract_json_payload
4
+
5
+ __all__ = ["extract_json_payload"]
@@ -545,9 +545,48 @@ def create_drift_measured_event(
545
545
  )
546
546
 
547
547
 
548
+ def create_execution_terminal_event(
549
+ execution_id: str,
550
+ session_id: str,
551
+ status: str,
552
+ *,
553
+ summary: dict[str, Any] | None = None,
554
+ error_message: str | None = None,
555
+ messages_processed: int = 0,
556
+ ) -> BaseEvent:
557
+ """Mirror a session terminal state into the execution event stream.
558
+
559
+ The orchestrator stores lifecycle events (started/completed/failed)
560
+ under ``aggregate_type="session"`` while runtime progress events use
561
+ ``aggregate_type="execution"``. TUI and other consumers that poll
562
+ only the execution stream would never see the terminal transition.
563
+
564
+ This helper emits an ``execution.terminal`` event under the execution
565
+ aggregate so that a single-stream consumer can detect completion
566
+ without polling a second channel.
567
+ """
568
+ data: dict[str, Any] = {
569
+ "session_id": session_id,
570
+ "status": status,
571
+ "messages_processed": messages_processed,
572
+ "timestamp": datetime.now(UTC).isoformat(),
573
+ }
574
+ if summary is not None:
575
+ data["summary"] = summary
576
+ if error_message is not None:
577
+ data["error_message"] = error_message
578
+ return BaseEvent(
579
+ type="execution.terminal",
580
+ aggregate_type="execution",
581
+ aggregate_id=execution_id,
582
+ data=data,
583
+ )
584
+
585
+
548
586
  __all__ = [
549
587
  "create_ac_stall_detected_event",
550
588
  "create_drift_measured_event",
589
+ "create_execution_terminal_event",
551
590
  "create_heartbeat_event",
552
591
  "create_mcp_tools_loaded_event",
553
592
  "create_progress_event",
@@ -43,6 +43,7 @@ from ouroboros.orchestrator.adapter import (
43
43
  )
44
44
  from ouroboros.orchestrator.events import (
45
45
  create_drift_measured_event,
46
+ create_execution_terminal_event,
46
47
  create_mcp_tools_loaded_event,
47
48
  create_progress_event,
48
49
  create_session_completed_event,
@@ -1145,6 +1146,17 @@ class OrchestratorRunner:
1145
1146
  error=str(cancel_result.error),
1146
1147
  )
1147
1148
 
1149
+ # Mirror cancellation into execution stream for TUI.
1150
+ await self._event_store.append(
1151
+ create_execution_terminal_event(
1152
+ execution_id=execution_id,
1153
+ session_id=session_id,
1154
+ status="cancelled",
1155
+ error_message="Execution cancelled by external request",
1156
+ messages_processed=messages_processed,
1157
+ )
1158
+ )
1159
+
1148
1160
  # Display cancellation notice
1149
1161
  self._console.print(
1150
1162
  Panel(
@@ -1532,6 +1544,19 @@ class OrchestratorRunner:
1532
1544
  )
1533
1545
  )
1534
1546
 
1547
+ # Mirror terminal state into the execution event stream so
1548
+ # single-stream consumers (TUI) detect completion without
1549
+ # polling the separate session aggregate.
1550
+ terminal_event = create_execution_terminal_event(
1551
+ execution_id=exec_id,
1552
+ session_id=tracker.session_id,
1553
+ status="completed" if success else "failed",
1554
+ summary=completion_summary if success else None,
1555
+ error_message=final_message if not success else None,
1556
+ messages_processed=messages_processed,
1557
+ )
1558
+ await self._event_store.append(terminal_event)
1559
+
1535
1560
  log.info(
1536
1561
  "orchestrator.runner.execute_completed",
1537
1562
  execution_id=exec_id,
@@ -1586,6 +1611,15 @@ class OrchestratorRunner:
1586
1611
  tracker.session_id,
1587
1612
  str(e),
1588
1613
  )
1614
+ await self._event_store.append(
1615
+ create_execution_terminal_event(
1616
+ execution_id=exec_id,
1617
+ session_id=tracker.session_id,
1618
+ status="failed",
1619
+ error_message=str(e),
1620
+ messages_processed=messages_processed,
1621
+ )
1622
+ )
1589
1623
 
1590
1624
  return Result.err(
1591
1625
  OrchestratorError(
@@ -1801,6 +1835,17 @@ class OrchestratorRunner:
1801
1835
  )
1802
1836
  )
1803
1837
 
1838
+ await self._event_store.append(
1839
+ create_execution_terminal_event(
1840
+ execution_id=exec_id,
1841
+ session_id=tracker.session_id,
1842
+ status="completed" if success else "failed",
1843
+ summary=execution_summary if success else None,
1844
+ error_message=final_message if not success else None,
1845
+ messages_processed=parallel_result.total_messages,
1846
+ )
1847
+ )
1848
+
1804
1849
  log.info(
1805
1850
  "orchestrator.runner.parallel_completed",
1806
1851
  execution_id=exec_id,
@@ -2131,6 +2176,20 @@ Note: This is a resumed session. Please continue from where execution was interr
2131
2176
  )
2132
2177
  )
2133
2178
 
2179
+ # Mirror terminal state into execution stream for TUI.
2180
+ terminal_status = (
2181
+ "completed" if success else ("paused" if recoverable_resume_failure else "failed")
2182
+ )
2183
+ await self._event_store.append(
2184
+ create_execution_terminal_event(
2185
+ execution_id=tracker.execution_id,
2186
+ session_id=session_id,
2187
+ status=terminal_status,
2188
+ error_message=final_message if not success else None,
2189
+ messages_processed=messages_processed,
2190
+ )
2191
+ )
2192
+
2134
2193
  log.info(
2135
2194
  "orchestrator.runner.resume_completed",
2136
2195
  session_id=session_id,
@@ -2170,6 +2229,14 @@ Note: This is a resumed session. Please continue from where execution was interr
2170
2229
  self._unregister_session(tracker.execution_id, session_id)
2171
2230
  if self._task_workspace is not None:
2172
2231
  release_lock(self._task_workspace.lock_path)
2232
+ await self._event_store.append(
2233
+ create_execution_terminal_event(
2234
+ execution_id=tracker.execution_id,
2235
+ session_id=session_id,
2236
+ status="failed",
2237
+ error_message=str(e),
2238
+ )
2239
+ )
2173
2240
 
2174
2241
  return Result.err(
2175
2242
  OrchestratorError(
@@ -35,6 +35,7 @@ from pathlib import Path
35
35
  import structlog
36
36
 
37
37
  from ouroboros.core.errors import ProviderError
38
+ from ouroboros.core.json_utils import extract_json_payload
38
39
  from ouroboros.core.types import Result
39
40
  from ouroboros.providers.base import (
40
41
  CompletionConfig,
@@ -48,6 +49,7 @@ log = structlog.get_logger(__name__)
48
49
 
49
50
  # Retry configuration for transient API errors
50
51
  _MAX_RETRIES = 5
52
+ _MAX_JSON_RETRIES = 3 # Extra retries when response_format requires JSON but LLM returns prose
51
53
  _INITIAL_BACKOFF_SECONDS = 2.0 # Increased for custom CLI startup
52
54
  _RETRYABLE_ERROR_PATTERNS = (
53
55
  "concurrency",
@@ -244,13 +246,35 @@ class ClaudeCodeAdapter:
244
246
  # output. When callers request a schema, reinforce the requirement in the
245
247
  # prompt text and let downstream parsers extract JSON from the plain-text
246
248
  # response rather than depending on SDK-level structured_output.
247
- if config.response_format and config.response_format.get("type") == "json_schema":
248
- schema = config.response_format.get("json_schema", {})
249
- schema_instruction = (
250
- "Respond with ONLY a valid JSON object that matches this schema. "
251
- "Do not use markdown fences, headers, or explanatory text.\n\n"
252
- f"JSON schema:\n{json.dumps(schema, indent=2, sort_keys=True)}"
253
- )
249
+ requires_json = bool(
250
+ config.response_format
251
+ and config.response_format.get("type") in ("json_schema", "json_object")
252
+ )
253
+ if requires_json:
254
+ fmt_type = config.response_format.get("type")
255
+ if fmt_type == "json_schema":
256
+ schema = config.response_format.get("json_schema", {})
257
+ # Derive the expected top-level type from the schema so the
258
+ # prompt instruction matches the schema contract (object, array, etc.)
259
+ top_type = schema.get("type", "object")
260
+ if top_type == "array":
261
+ type_noun = "JSON array"
262
+ elif top_type == "object":
263
+ type_noun = "JSON object"
264
+ else:
265
+ # Primitive schemas (string, number, boolean, null)
266
+ type_noun = "JSON value"
267
+ schema_instruction = (
268
+ f"Respond with ONLY a valid {type_noun} that matches this schema. "
269
+ "Do not use markdown fences, headers, or explanatory text.\n\n"
270
+ f"JSON schema:\n{json.dumps(schema, indent=2, sort_keys=True)}"
271
+ )
272
+ else:
273
+ # json_object — no schema, but still steer toward JSON
274
+ schema_instruction = (
275
+ "Respond with ONLY a valid JSON object. "
276
+ "Do not use markdown fences, headers, or explanatory text."
277
+ )
254
278
  if system_prompt:
255
279
  system_prompt = f"{system_prompt}\n\n{schema_instruction}"
256
280
  else:
@@ -269,6 +293,98 @@ class ClaudeCodeAdapter:
269
293
  has_system_prompt=system_prompt is not None,
270
294
  )
271
295
 
296
+ result = await self._complete_with_transient_retry(prompt, config, system_prompt)
297
+
298
+ # JSON enforcement layer: if response_format requires JSON,
299
+ # normalize or retry until we get valid JSON.
300
+ if requires_json and result.is_ok:
301
+ result = await self._enforce_json(result, prompt, config, system_prompt)
302
+
303
+ return result
304
+
305
+ def _normalize_json_content(
306
+ self, result: Result[CompletionResponse, ProviderError]
307
+ ) -> Result[CompletionResponse, ProviderError] | None:
308
+ """Try to extract and normalize JSON from a successful result.
309
+
310
+ Returns:
311
+ Normalized result if JSON found, None if no valid JSON in content.
312
+ """
313
+ if result.is_err:
314
+ return result
315
+ extracted = extract_json_payload(result.value.content)
316
+ if extracted:
317
+ result.value.content = extracted
318
+ return result
319
+ return None
320
+
321
+ async def _enforce_json(
322
+ self,
323
+ result: Result[CompletionResponse, ProviderError],
324
+ prompt: str,
325
+ config: CompletionConfig,
326
+ system_prompt: str | None,
327
+ ) -> Result[CompletionResponse, ProviderError]:
328
+ """Normalize JSON content or retry until valid JSON is obtained.
329
+
330
+ If the response contains valid JSON (even wrapped in prose/fences),
331
+ extract and return just the JSON. If no valid JSON, retry up to
332
+ _MAX_JSON_RETRIES times. If all retries fail, return an error.
333
+ """
334
+ # Try to normalize the initial result
335
+ normalized = self._normalize_json_content(result)
336
+ if normalized is not None:
337
+ return normalized
338
+
339
+ log.warning(
340
+ "claude_code_adapter.json_not_found",
341
+ max_json_retries=_MAX_JSON_RETRIES,
342
+ response_preview=result.value.content[:120],
343
+ )
344
+
345
+ for json_attempt in range(1, _MAX_JSON_RETRIES + 1):
346
+ log.info(
347
+ "claude_code_adapter.json_retry",
348
+ attempt=json_attempt,
349
+ max_json_retries=_MAX_JSON_RETRIES,
350
+ )
351
+ result = await self._complete_with_transient_retry(prompt, config, system_prompt)
352
+ if result.is_err:
353
+ return result
354
+ normalized = self._normalize_json_content(result)
355
+ if normalized is not None:
356
+ return normalized
357
+
358
+ # All retries exhausted — return error instead of prose
359
+ log.error(
360
+ "claude_code_adapter.json_retries_exhausted",
361
+ max_json_retries=_MAX_JSON_RETRIES,
362
+ response_preview=result.value.content[:120] if result.is_ok else "N/A",
363
+ )
364
+ return Result.err(
365
+ ProviderError(
366
+ message=(
367
+ f"JSON format required but LLM returned prose after {_MAX_JSON_RETRIES} retries"
368
+ ),
369
+ details={
370
+ "last_response_preview": (
371
+ result.value.content[:200] if result.is_ok else "N/A"
372
+ ),
373
+ },
374
+ )
375
+ )
376
+
377
+ async def _complete_with_transient_retry(
378
+ self,
379
+ prompt: str,
380
+ config: CompletionConfig,
381
+ system_prompt: str | None,
382
+ ) -> Result[CompletionResponse, ProviderError]:
383
+ """Inner retry loop for transient API errors (rate limits, timeouts, etc.).
384
+
385
+ This handles infrastructure-level failures only. JSON format
386
+ enforcement is handled by the caller.
387
+ """
272
388
  last_error: ProviderError | None = None
273
389
 
274
390
  for attempt in range(_MAX_RETRIES):
@@ -257,6 +257,12 @@ class OuroborosTUI(App[None]):
257
257
  self._state.status = "failed"
258
258
  elif event_type == "orchestrator.session.cancelled":
259
259
  self._state.status = "cancelled"
260
+ elif event_type == "execution.terminal":
261
+ # Mirror event from the execution stream — ensures TUI sees
262
+ # terminal transitions even when only polling "execution".
263
+ terminal_status = data.get("status", "completed")
264
+ if terminal_status in {"completed", "failed", "cancelled"}:
265
+ self._state.status = terminal_status
260
266
  elif event_type == "orchestrator.session.paused":
261
267
  self._state.status = "paused"
262
268
  self._state.is_paused = True
@@ -665,6 +665,14 @@ def create_message_from_event(event: BaseEvent) -> Message | None:
665
665
  data=data,
666
666
  )
667
667
 
668
+ elif event_type == "execution.terminal":
669
+ return ExecutionUpdated(
670
+ execution_id=event.aggregate_id,
671
+ session_id=data.get("session_id", ""),
672
+ status=data.get("status", "completed"),
673
+ data=data,
674
+ )
675
+
668
676
  elif event_type == "execution.phase.completed":
669
677
  return PhaseChanged(
670
678
  execution_id=event.aggregate_id,
@@ -99,3 +99,51 @@ class TestExtractJsonPayload:
99
99
  result = extract_json_payload(text)
100
100
  assert result is not None
101
101
  assert '"valid": true' in result
102
+
103
+
104
+ class TestExtractJsonArray:
105
+ """extract_json_payload must also handle top-level JSON arrays."""
106
+
107
+ def test_pure_array(self):
108
+ text = '[{"a": 1}, {"b": 2}]'
109
+ result = extract_json_payload(text)
110
+ assert result is not None
111
+ assert '"a": 1' in result
112
+ assert result.startswith("[")
113
+
114
+ def test_array_in_code_fence(self):
115
+ text = '```json\n[{"item": "value"}]\n```'
116
+ result = extract_json_payload(text)
117
+ assert result is not None
118
+ assert result.startswith("[")
119
+
120
+ def test_prose_before_array(self):
121
+ text = 'Here are the results:\n[{"score": 0.9}, {"score": 0.8}]'
122
+ result = extract_json_payload(text)
123
+ assert result is not None
124
+ assert result.startswith("[")
125
+ assert '"score": 0.9' in result
126
+
127
+ def test_object_before_array_returns_object(self):
128
+ """When both object and array exist, return whichever comes first."""
129
+ text = '{"first": true} [1, 2, 3]'
130
+ result = extract_json_payload(text)
131
+ assert result is not None
132
+ assert '"first": true' in result
133
+
134
+ def test_array_before_object_returns_array(self):
135
+ text = '[1, 2] {"second": true}'
136
+ result = extract_json_payload(text)
137
+ assert result is not None
138
+ assert result == "[1, 2]"
139
+
140
+ def test_empty_array(self):
141
+ text = "prefix [] suffix"
142
+ result = extract_json_payload(text)
143
+ assert result == "[]"
144
+
145
+ def test_nested_array(self):
146
+ text = "[[1, 2], [3, 4]]"
147
+ result = extract_json_payload(text)
148
+ assert result is not None
149
+ assert result == "[[1, 2], [3, 4]]"