whiletrue 0.1.0__tar.gz → 0.2.0__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.
Files changed (243) hide show
  1. {whiletrue-0.1.0 → whiletrue-0.2.0}/CHANGELOG.md +10 -0
  2. whiletrue-0.2.0/PKG-INFO +280 -0
  3. whiletrue-0.2.0/README.md +253 -0
  4. whiletrue-0.2.0/THIRD_PARTY_NOTICES.md +32 -0
  5. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/README.md +4 -0
  6. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/architecture.md +70 -0
  7. whiletrue-0.2.0/docs/assets/architecture.svg +51 -0
  8. whiletrue-0.2.0/docs/assets/demo-real.svg +1 -0
  9. whiletrue-0.2.0/docs/assets/issue-loop.svg +17 -0
  10. whiletrue-0.2.0/docs/assets/logo.svg +7 -0
  11. whiletrue-0.2.0/docs/assets/ralph-loop.svg +17 -0
  12. whiletrue-0.2.0/docs/assets/rsi-architecture.svg +69 -0
  13. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/cli.md +5 -0
  14. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/getting-started.md +2 -0
  15. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/open-questions.md +8 -0
  16. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/plan.md +26 -2
  17. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/reference.md +11 -0
  18. whiletrue-0.2.0/docs/rsi-plan.md +121 -0
  19. whiletrue-0.2.0/docs/rsi.md +127 -0
  20. whiletrue-0.2.0/docs/spike-rsi.md +66 -0
  21. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/todo.md +51 -3
  22. whiletrue-0.2.0/docs/tutorial.md +250 -0
  23. {whiletrue-0.1.0 → whiletrue-0.2.0}/pyproject.toml +6 -4
  24. whiletrue-0.2.0/scripts/check_provenance.py +63 -0
  25. {whiletrue-0.1.0 → whiletrue-0.2.0}/scripts/docs_check.py +4 -1
  26. whiletrue-0.2.0/tests/fixtures/fake_rsi_claude.py +65 -0
  27. whiletrue-0.2.0/tests/integration/test_rsi_cli.py +166 -0
  28. whiletrue-0.2.0/tests/live/test_live_rsi.py +69 -0
  29. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_agent.py +29 -1
  30. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_headless.py +16 -0
  31. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_runtime.py +39 -0
  32. whiletrue-0.2.0/tests/unit/rsi/harness2/conftest.py +219 -0
  33. whiletrue-0.2.0/tests/unit/rsi/harness2/test_apply_adopt.py +340 -0
  34. whiletrue-0.2.0/tests/unit/rsi/harness2/test_context_library_selection.py +162 -0
  35. whiletrue-0.2.0/tests/unit/rsi/harness2/test_edges.py +217 -0
  36. whiletrue-0.2.0/tests/unit/rsi/harness2/test_prompts.py +68 -0
  37. whiletrue-0.2.0/tests/unit/rsi/harness2/test_runmark_ledger.py +79 -0
  38. whiletrue-0.2.0/tests/unit/rsi/harness2/test_sessions_proposal.py +133 -0
  39. whiletrue-0.2.0/tests/unit/rsi/harness2/test_snapshot_trajectory.py +177 -0
  40. whiletrue-0.2.0/tests/unit/rsi/harness2/test_strategy.py +174 -0
  41. whiletrue-0.2.0/tests/unit/rsi/harness2/test_tree.py +179 -0
  42. whiletrue-0.2.0/tests/unit/test_provenance.py +80 -0
  43. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/tmux/test_controller.py +37 -0
  44. whiletrue-0.2.0/third_party/README.md +7 -0
  45. whiletrue-0.2.0/third_party/harness2/LICENSE +202 -0
  46. whiletrue-0.2.0/third_party/harness2/PROVENANCE.md +44 -0
  47. {whiletrue-0.1.0 → whiletrue-0.2.0}/uv.lock +1 -1
  48. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/agent.py +12 -2
  49. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/headless.py +2 -0
  50. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/app.py +31 -2
  51. whiletrue-0.2.0/whiletrue/cli/rsi_cmd.py +142 -0
  52. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/runner.py +3 -0
  53. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/runtime.py +4 -1
  54. whiletrue-0.2.0/whiletrue/rsi/__init__.py +25 -0
  55. whiletrue-0.2.0/whiletrue/rsi/harness2/__init__.py +4 -0
  56. whiletrue-0.2.0/whiletrue/rsi/harness2/adopt.py +113 -0
  57. whiletrue-0.2.0/whiletrue/rsi/harness2/apply.py +159 -0
  58. whiletrue-0.2.0/whiletrue/rsi/harness2/config.py +140 -0
  59. whiletrue-0.2.0/whiletrue/rsi/harness2/context.py +285 -0
  60. whiletrue-0.2.0/whiletrue/rsi/harness2/env.py +63 -0
  61. whiletrue-0.2.0/whiletrue/rsi/harness2/ledger.py +128 -0
  62. whiletrue-0.2.0/whiletrue/rsi/harness2/library.py +206 -0
  63. whiletrue-0.2.0/whiletrue/rsi/harness2/prompts.py +572 -0
  64. whiletrue-0.2.0/whiletrue/rsi/harness2/proposal.py +122 -0
  65. whiletrue-0.2.0/whiletrue/rsi/harness2/rollout.py +156 -0
  66. whiletrue-0.2.0/whiletrue/rsi/harness2/runmark.py +120 -0
  67. whiletrue-0.2.0/whiletrue/rsi/harness2/selection.py +118 -0
  68. whiletrue-0.2.0/whiletrue/rsi/harness2/sessions.py +357 -0
  69. whiletrue-0.2.0/whiletrue/rsi/harness2/snapshot.py +235 -0
  70. whiletrue-0.2.0/whiletrue/rsi/harness2/strategy.py +432 -0
  71. whiletrue-0.2.0/whiletrue/rsi/harness2/surfaces.py +182 -0
  72. whiletrue-0.2.0/whiletrue/rsi/harness2/trajectory.py +86 -0
  73. whiletrue-0.2.0/whiletrue/rsi/harness2/tree.py +426 -0
  74. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/tmux/controller.py +13 -0
  75. whiletrue-0.1.0/PKG-INFO +0 -48
  76. whiletrue-0.1.0/README.md +0 -23
  77. {whiletrue-0.1.0 → whiletrue-0.2.0}/.editorconfig +0 -0
  78. {whiletrue-0.1.0 → whiletrue-0.2.0}/.envrc +0 -0
  79. {whiletrue-0.1.0 → whiletrue-0.2.0}/.github/ISSUE_TEMPLATE/task.md +0 -0
  80. {whiletrue-0.1.0 → whiletrue-0.2.0}/.github/pull_request_template.md +0 -0
  81. {whiletrue-0.1.0 → whiletrue-0.2.0}/.github/workflows/ci.yml +0 -0
  82. {whiletrue-0.1.0 → whiletrue-0.2.0}/.github/workflows/release.yml +0 -0
  83. {whiletrue-0.1.0 → whiletrue-0.2.0}/.gitignore +0 -0
  84. {whiletrue-0.1.0 → whiletrue-0.2.0}/CLAUDE.md +0 -0
  85. {whiletrue-0.1.0 → whiletrue-0.2.0}/LICENSE +0 -0
  86. {whiletrue-0.1.0 → whiletrue-0.2.0}/devenv.lock +0 -0
  87. {whiletrue-0.1.0 → whiletrue-0.2.0}/devenv.nix +0 -0
  88. {whiletrue-0.1.0 → whiletrue-0.2.0}/devenv.yaml +0 -0
  89. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/authoring.md +0 -0
  90. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/conventions.md +0 -0
  91. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/developing.md +0 -0
  92. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/m0-smoke.md +0 -0
  93. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/plugins.md +0 -0
  94. {whiletrue-0.1.0 → whiletrue-0.2.0}/docs/spike-interactive.md +0 -0
  95. {whiletrue-0.1.0 → whiletrue-0.2.0}/examples/issue-loop/README.md +0 -0
  96. {whiletrue-0.1.0 → whiletrue-0.2.0}/examples/issue-loop/agents/fix.md +0 -0
  97. {whiletrue-0.1.0 → whiletrue-0.2.0}/examples/issue-loop/agents/implement.md +0 -0
  98. {whiletrue-0.1.0 → whiletrue-0.2.0}/examples/issue-loop/agents/respond.md +0 -0
  99. {whiletrue-0.1.0 → whiletrue-0.2.0}/examples/issue-loop/whiletrue.yaml +0 -0
  100. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/conftest.py +0 -0
  101. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/fixtures/fake_interactive_claude.py +0 -0
  102. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_cli.py +0 -0
  103. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_cli_surface.py +0 -0
  104. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_gates_cli.py +0 -0
  105. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_interactive_run.py +0 -0
  106. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_issue_loop.py +0 -0
  107. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_m3_exit.py +0 -0
  108. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_ops_cli.py +0 -0
  109. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/integration/test_recipes.py +0 -0
  110. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/live/test_live_backends.py +0 -0
  111. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_exec.py +0 -0
  112. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_gates.py +0 -0
  113. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_history.py +0 -0
  114. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_human.py +0 -0
  115. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_json_source.py +0 -0
  116. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_markdown_source.py +0 -0
  117. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_plugin.py +0 -0
  118. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_process.py +0 -0
  119. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_sessions.py +0 -0
  120. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/basics/test_shell.py +0 -0
  121. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_endpoint.py +0 -0
  122. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_interactive.py +0 -0
  123. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_panes.py +0 -0
  124. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_plugin_scripts.py +0 -0
  125. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_session.py +0 -0
  126. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/claude_code/test_transcript.py +0 -0
  127. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/codex/test_runner.py +0 -0
  128. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/control/test_control.py +0 -0
  129. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_cache.py +0 -0
  130. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_caps.py +0 -0
  131. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_composite.py +0 -0
  132. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_config.py +0 -0
  133. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_context.py +0 -0
  134. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_duration.py +0 -0
  135. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_events.py +0 -0
  136. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_expr.py +0 -0
  137. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_history_store.py +0 -0
  138. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_lock.py +0 -0
  139. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_memory_store.py +0 -0
  140. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_module.py +0 -0
  141. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_outcomes.py +0 -0
  142. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_registry.py +0 -0
  143. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_replay.py +0 -0
  144. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_template.py +0 -0
  145. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_validate.py +0 -0
  146. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/core/test_wake.py +0 -0
  147. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/git/test_git.py +0 -0
  148. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/github/test_client.py +0 -0
  149. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/github/test_filebacked.py +0 -0
  150. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/github/test_plugin.py +0 -0
  151. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/github/test_specs.py +0 -0
  152. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/opencode/test_runner.py +0 -0
  153. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/store_sqlite/test_sqlite_store.py +0 -0
  154. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/test_abort.py +0 -0
  155. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/test_architecture.py +0 -0
  156. {whiletrue-0.1.0 → whiletrue-0.2.0}/tests/unit/test_panel.py +0 -0
  157. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/__init__.py +0 -0
  158. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/__main__.py +0 -0
  159. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/abort.py +0 -0
  160. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/__init__.py +0 -0
  161. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/comments.py +0 -0
  162. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/diff_size.py +0 -0
  163. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/exec_.py +0 -0
  164. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/history.py +0 -0
  165. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/human.py +0 -0
  166. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/json_source.py +0 -0
  167. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/markdown_source.py +0 -0
  168. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/process.py +0 -0
  169. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/sessions.py +0 -0
  170. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/set_.py +0 -0
  171. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/shell.py +0 -0
  172. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/basics/wake.py +0 -0
  173. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/__init__.py +0 -0
  174. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/endpoint.py +0 -0
  175. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/interactive.py +0 -0
  176. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/learnings.py +0 -0
  177. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/panes.py +0 -0
  178. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/plugin/.claude-plugin/plugin.json +0 -0
  179. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/plugin/hook.py +0 -0
  180. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/plugin/hooks/hooks.json +0 -0
  181. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/plugin/mcp_server.py +0 -0
  182. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/session.py +0 -0
  183. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/claude_code/transcript.py +0 -0
  184. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/__init__.py +0 -0
  185. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/__main__.py +0 -0
  186. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/common.py +0 -0
  187. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/gates.py +0 -0
  188. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/ops.py +0 -0
  189. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/panel.py +0 -0
  190. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/registry.py +0 -0
  191. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/cli/templates.py +0 -0
  192. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/codex/__init__.py +0 -0
  193. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/codex/runner.py +0 -0
  194. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/__init__.py +0 -0
  195. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/chain.py +0 -0
  196. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/loop.py +0 -0
  197. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/map_.py +0 -0
  198. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/parallel.py +0 -0
  199. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/retry.py +0 -0
  200. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/sequence.py +0 -0
  201. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/control/switch.py +0 -0
  202. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/__init__.py +0 -0
  203. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/caps.py +0 -0
  204. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/comments.py +0 -0
  205. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/composite.py +0 -0
  206. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/config.py +0 -0
  207. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/context.py +0 -0
  208. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/duration.py +0 -0
  209. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/events.py +0 -0
  210. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/expr.py +0 -0
  211. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/history.py +0 -0
  212. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/lock.py +0 -0
  213. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/memory_store.py +0 -0
  214. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/module.py +0 -0
  215. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/outcomes.py +0 -0
  216. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/registry.py +0 -0
  217. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/replay.py +0 -0
  218. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/source.py +0 -0
  219. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/store.py +0 -0
  220. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/template.py +0 -0
  221. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/validate.py +0 -0
  222. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/wake.py +0 -0
  223. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/core/workspace.py +0 -0
  224. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/git/__init__.py +0 -0
  225. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/git/modules.py +0 -0
  226. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/git/workspaces.py +0 -0
  227. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/github/__init__.py +0 -0
  228. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/github/client.py +0 -0
  229. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/github/filebacked.py +0 -0
  230. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/github/memory.py +0 -0
  231. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/github/plugin.py +0 -0
  232. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/github/specs.py +0 -0
  233. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/opencode/__init__.py +0 -0
  234. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/opencode/runner.py +0 -0
  235. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/py.typed +0 -0
  236. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/recipes/issue-loop.yaml +0 -0
  237. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/recipes/ralph.yaml +0 -0
  238. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/recipes/review-pass.yaml +0 -0
  239. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/recipes/review-respond.yaml +0 -0
  240. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/store_sqlite/__init__.py +0 -0
  241. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/store_sqlite/migrations.py +0 -0
  242. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/store_sqlite/sqlite_store.py +0 -0
  243. {whiletrue-0.1.0 → whiletrue-0.2.0}/whiletrue/tmux/__init__.py +0 -0
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ - **Recursive self-improvement (`rsi`), off by default.** The Harness² method (Xu et al., arXiv:2610.14224) ported into `whiletrue.rsi.harness2`: isolated rollouts, improver sessions that edit the harness, composition, blind selection, a per-domain experience library, human-approved adoption, `rsi.budget_usd` and the R = 4k / P = 3k budget identity. New: top-level `rsi:` setting, strategy `rsi.harness2`, `whiletrue rsi status|diff|library|adopt|reset`. Claude Code and Codex surfaces. Apache-2.0 code keeps its headers; see THIRD_PARTY_NOTICES.md. Guide: docs/rsi.md.
6
+ - Core: a scope can redirect its steps to another directory (`cwd`), runners can pass raw messages (`RunContext.on_raw`), agents expose an event tap, and the item scope has `project_dir`.
7
+
8
+ ## 0.1.1
9
+
10
+ - Fixed: parallel interactive items raced to create the tmux session. The loser failed with `duplicate session` and that error was fed to the agent as its previous failure. Session and pane creation now run one at a time, and parallel agents share one window grid.
11
+ - Docs: a new README with a recording of a real run, architecture and flow diagrams, and a step-by-step tutorial (`docs/tutorial.md`).
12
+
3
13
  ## 0.1.0 (first release)
4
14
 
5
15
  whiletrue runs configurable pipelines of agentic and deterministic steps around coding agents.
@@ -0,0 +1,280 @@
1
+ Metadata-Version: 2.5
2
+ Name: whiletrue
3
+ Version: 0.2.0
4
+ Summary: Local orchestrator that runs pipelines of agent and deterministic steps around Claude Code, opencode and Codex, with gates, human approval, parallel git worktrees and crash-safe resume.
5
+ Project-URL: Repository, https://github.com/dariussingh/whiletrue
6
+ Project-URL: Changelog, https://github.com/dariussingh/whiletrue/blob/main/CHANGELOG.md
7
+ Project-URL: Documentation, https://github.com/dariussingh/whiletrue/tree/main/docs
8
+ Author: Darius Singh
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ License-File: THIRD_PARTY_NOTICES.md
12
+ License-File: third_party/harness2/LICENSE
13
+ Keywords: agents,ai-agents,claude-code,codex,coding-agents,git-worktree,human-in-the-loop,opencode,orchestration,pipelines,ralph,recursive-self-improvement,tmux
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: POSIX
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Build Tools
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: common-expression-language<1,>=0.10
24
+ Requires-Dist: pydantic<3,>=2.9
25
+ Requires-Dist: pyyaml<7,>=6
26
+ Description-Content-Type: text/markdown
27
+
28
+ <div align="center">
29
+
30
+ <img src="docs/assets/logo.svg" alt="whiletrue logo" width="96" height="96">
31
+
32
+ # whiletrue
33
+
34
+ **The loop around your coding agents.**
35
+
36
+ Run pipelines of agentic and deterministic steps around Claude Code, opencode and Codex, locally, with gates, humans in the loop, and crash-safe resume.
37
+
38
+ [![PyPI](https://img.shields.io/pypi/v/whiletrue?logo=pypi&logoColor=white)](https://pypi.org/project/whiletrue/)
39
+ [![Python](https://img.shields.io/pypi/pyversions/whiletrue?logo=python&logoColor=white)](https://pypi.org/project/whiletrue/)
40
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
41
+ [![Docs](https://img.shields.io/badge/docs-docs%2F-informational)](docs/README.md)
42
+
43
+ </div>
44
+
45
+ > LangGraph builds the agent; whiletrue runs the loop around agents you already have.
46
+
47
+ <div align="center">
48
+
49
+ <img src="docs/assets/demo-real.svg" alt="Recording of a real run: two Claude Code agents work in parallel in tmux panes while a control panel and shell show status, both items pass their pytest gate and park for human approval, then approve and resume finish them" width="900">
50
+
51
+ <sub>A real run, not a mock-up: two Claude Code agents in parallel, a pytest gate, a human approval and a resume, about $0.23 in total. Captured from the live tmux panes; the two tmux windows are drawn side by side.</sub>
52
+
53
+ </div>
54
+
55
+ ```bash
56
+ uvx whiletrue init # scaffold a Ralph loop
57
+ uvx whiletrue run # agent -> pytest gate -> repeat until green
58
+ ```
59
+
60
+ ## Overview
61
+
62
+ Coding agents are good at one task and bad at finishing a backlog unattended. whiletrue is the orchestrator you put around them. You describe the loop in a single `whiletrue.yaml`: which agent does the work, which deterministic gate checks it, when to retry, when to ask a person. whiletrue validates the config before spending a token, runs it, and records every step so you can inspect, replay or resume it.
63
+
64
+ - **Pipelines, not prompts.** Agent steps, shell and git steps, and gates compose with `sequence`, `loop`, `map`, `parallel`, `switch`, `retry`, `try` and `human.approve`. Every loop is bounded.
65
+ - **Any backend.** `claude-code-headless`, `claude-code` (the real interactive CLI in a tmux pane you can type into), `opencode` and `codex`. Mix them in one pipeline.
66
+ - **Many items at once.** One item per task or GitHub issue, each in its own git worktree, with `parallel: N` and a cap on live agent sessions.
67
+ - **Humans in the loop.** A gate parks an item until a person approves, rejects or comments; other items keep running. Every review comment gets an answer.
68
+ - **Durable.** State lives in SQLite. Kill the process at any point and `whiletrue resume` replays finished steps instead of redoing them; side effects (PRs, merges, replies) happen exactly once.
69
+ - **Local.** One machine, no server, no account. Everything is a file in your repo plus `.whiletrue/`.
70
+
71
+ ## Contents
72
+
73
+ - [Install](#install)
74
+ - [Quickstart](#quickstart)
75
+ - [Architecture](#architecture)
76
+ - [Concepts](#concepts)
77
+ - [Examples](#examples)
78
+ - [Backends](#backends)
79
+ - [CLI](#cli)
80
+ - [Documentation](#documentation)
81
+ - [Development](#development)
82
+ - [License](#license)
83
+
84
+ ## Install
85
+
86
+ Requires Python 3.12+ and at least one agent CLI on your `PATH` ([Claude Code](https://claude.com/claude-code), [opencode](https://opencode.ai) or [Codex](https://github.com/openai/codex)). `git` is needed for worktrees, `tmux` for interactive agents, and `gh` for the GitHub integration.
87
+
88
+ ```bash
89
+ uv tool install whiletrue # or: pip install whiletrue
90
+ whiletrue --help
91
+
92
+ uvx whiletrue --help # or run it without installing
93
+ ```
94
+
95
+ If an agent CLI is not on `PATH`, set `WHILETRUE_CLAUDE_BIN`, `WHILETRUE_OPENCODE_BIN` or `WHILETRUE_CODEX_BIN`.
96
+
97
+ ## Quickstart
98
+
99
+ ```bash
100
+ cd my-project
101
+ whiletrue init # writes whiletrue.yaml and agents/ralph.md
102
+ whiletrue validate # config, wiring, limits and safety rules; spends nothing
103
+ whiletrue plan # prints the expanded step tree; spends nothing
104
+ whiletrue run # runs it
105
+ whiletrue status # steps, outcomes and cost of the latest run
106
+ ```
107
+
108
+ The scaffold is a Ralph loop. The agent runs in a fresh context, a deterministic `pytest` gate checks the result, and the loop repeats (at most 5 times) until the gate is green:
109
+
110
+ ```yaml
111
+ # whiletrue.yaml
112
+ name: ralph
113
+ pipeline:
114
+ loop:
115
+ max: 5 # every loop is bounded; `max: unbounded` is an explicit opt-out
116
+ do:
117
+ - agent: { uses: ./agents/ralph.md }
118
+ - gate.shell: { run: "pytest" }
119
+ ```
120
+
121
+ ```markdown
122
+ ---
123
+ # agents/ralph.md
124
+ agent: ralph
125
+ runner: claude-code-headless
126
+ permission_mode: acceptEdits
127
+ tools: [Read, Edit, Write, "Bash(pytest*)", "Bash(git *)"]
128
+ limits: { budget_usd: 2, turns: 40, wall: 20m }
129
+ ---
130
+ Work through the next unfinished item in TODO.md. Make the tests pass.
131
+
132
+ Failure output from the previous attempt (empty on the first try):
133
+ {{iter.previous}}
134
+ ```
135
+
136
+ Every agent must declare `limits`; `validate` refuses the config otherwise.
137
+
138
+ ## Architecture
139
+
140
+ <img src="docs/assets/architecture.svg" alt="Architecture: whiletrue.yaml and the CLI drive the core engine (loader, scheduler, pipeline runtime, park and resume, plugin registry, SQLite store); built-in plugins connect it to agent CLIs, git, GitHub and tmux" width="900">
141
+
142
+ The core knows nothing about git, GitHub, tmux or any agent. Every integration is a plugin built on the public plugin API, including the optional `rsi` layer, so you can add your own ([plugins](docs/plugins.md), [architecture](docs/architecture.md)).
143
+
144
+ ## Concepts
145
+
146
+ | Concept | What it is |
147
+ | --- | --- |
148
+ | **Pipeline** | A list of steps, or one strategy, in `whiletrue.yaml`. |
149
+ | **Step** | An action: `agent`, a shell command, a git or GitHub operation, a gate. Pure, deterministic, agentic or side-effecting. |
150
+ | **Strategy** | Control flow over steps: `sequence`, `tap`, `loop`, `map`, `parallel`, `switch`, `retry`, `try`, `human.approve`. |
151
+ | **Outcome ports** | Every step ends on `ok`, `fail`, `needs_human`, `skip` or `rejected`. `wires:` routes a port to another step; back-wires make loops. |
152
+ | **Item** | One unit of work from a `source:` (`json`, `markdown_tasks`, `github_issues`). Items run in parallel, in dependency order. |
153
+ | **Workspace** | Per-item checkout: `git-worktree`, `dir-copy` or `none`. |
154
+ | **Gate** | A deterministic check, or a human decision, that an item must pass. |
155
+ | **Recipe** | A ready-made composite: `ralph`, `review-pass`, `review-respond`, `issue-loop`. |
156
+ | **Run record** | The SQLite log of steps, parks, effects, comments and cost that makes replay and resume possible. |
157
+
158
+ Details: [reference](docs/reference.md), [authoring guide](docs/authoring.md), [architecture](docs/architecture.md).
159
+
160
+ ## Examples
161
+
162
+ ### A Ralph loop
163
+
164
+ <img src="docs/assets/ralph-loop.svg" alt="Ralph loop: agent in a fresh context, then a pytest gate; green ends the loop, red feeds the output back to the agent" width="900">
165
+
166
+ This is what `whiletrue init` scaffolds. See the YAML under [Quickstart](#quickstart).
167
+
168
+ ### Review loop with a read-only reviewer
169
+
170
+ ```yaml
171
+ pipeline:
172
+ composite:
173
+ uses: "recipe:review-pass"
174
+ params: { reviewer: ./agents/review.md, fixer: ./agents/fix.md, max_rounds: 3 }
175
+ ```
176
+
177
+ ### A backlog in parallel worktrees
178
+
179
+ ```yaml
180
+ parallel: 4
181
+ max_agents: 4
182
+ source: { markdown_tasks: { path: TASKS.md } } # - [ ] Title {#id after=other}
183
+ workspace: { git-worktree: { branch: "wt/{{item.id}}" } }
184
+ pipeline:
185
+ loop:
186
+ max: 5
187
+ do:
188
+ - agent: { uses: ./agents/implement.md }
189
+ - gate.shell: { run: "pytest" }
190
+ ```
191
+
192
+ ### A human gate on a pull request
193
+
194
+ ```yaml
195
+ - id: review
196
+ human.approve:
197
+ what: pr
198
+ wake: { any: [cli, { github.pr_review: any }] }
199
+ do:
200
+ - composite: { uses: "recipe:review-respond", params: { responder: ./agents/respond.md } }
201
+ wires: { rejected: fix }
202
+ ```
203
+
204
+ ```bash
205
+ whiletrue run # parks at the gate and exits with code 2
206
+ whiletrue status # lists what is waiting
207
+ whiletrue approve 12 # or: reject 12 --note "what to change"
208
+ whiletrue resume # finished steps are replayed, never redone
209
+ ```
210
+
211
+ ### The reference pipeline: issues with a human in the loop
212
+
213
+ [`examples/issue-loop`](examples/issue-loop/README.md) takes every issue in a GitHub milestone from open to merged: implement in a worktree, run the gate, open a PR, answer review comments, merge, close. You review every PR, and every comment you leave gets an answer.
214
+
215
+ <img src="docs/assets/issue-loop.svg" alt="Issue loop flow: implement with retry and a gate, open a PR, a human review gate with comment replies and a fix branch on rejection, then sync, a merge approval and the merge" width="900">
216
+
217
+ ## Backends
218
+
219
+ Choose per agent with `runner:`.
220
+
221
+ | Runner | Runs | Notes |
222
+ | --- | --- | --- |
223
+ | `claude-code-headless` | `claude -p` | Default. Budget, turns and wall limits enforced. |
224
+ | `claude-code` | Interactive Claude Code in a tmux pane | Watch it, type into it (recorded as a *steer*). Submits through a bundled MCP tool and hooks. |
225
+ | `opencode` | `opencode run` | Structured output checked against the step's cap. |
226
+ | `codex` | `codex exec` | Sandbox derived from `permission_mode`. No budget enforcement. |
227
+
228
+ Structured `outputs:` work on all of them. See [choosing a backend](docs/authoring.md#choosing-a-backend).
229
+
230
+ ## CLI
231
+
232
+ | Command | Purpose |
233
+ | --- | --- |
234
+ | `init`, `validate`, `plan` | Scaffold, check and preview a pipeline without spending tokens. |
235
+ | `run`, `resume`, `rerun`, `cancel` | Start, continue after a park or crash, redo, or stop items. |
236
+ | `status`, `logs`, `cost`, `replay` | Inspect runs, steps and spend; replay a recorded run. |
237
+ | `approve`, `reject`, `comment` | Decide human gates and talk to waiting items. |
238
+ | `attach`, `panel` | Open the tmux session and the live control panel. |
239
+ | `history`, `learnings` | Audit trail and approved lessons for future agents. |
240
+ | `lock` | Show or clear the run lock. |
241
+
242
+ Full reference: [docs/cli.md](docs/cli.md). New here? Follow the [tutorial](docs/tutorial.md).
243
+
244
+ ## Documentation
245
+
246
+ Start at [docs/README.md](docs/README.md).
247
+
248
+ - [Tutorial](docs/tutorial.md): from an empty folder to your own loop with gates, a reviewer, parallel tasks and a human approval.
249
+ - [Getting started](docs/getting-started.md): a longer walkthrough, including interactive agents, gates and parallel items.
250
+ - [Authoring guide](docs/authoring.md): writing pipelines and agents.
251
+ - [Reference](docs/reference.md): every module, strategy, provider and config key.
252
+ - [CLI](docs/cli.md) and [plugins](docs/plugins.md): the command line and extending whiletrue.
253
+ - [Architecture](docs/architecture.md), [plan](docs/plan.md), [todo](docs/todo.md) and [changelog](CHANGELOG.md).
254
+
255
+ ## Development
256
+
257
+ Requires [devenv](https://devenv.sh) (or Python 3.12 + [uv](https://docs.astral.sh/uv/)). See [developing.md](docs/developing.md).
258
+
259
+ ```bash
260
+ git clone https://github.com/dariussingh/whiletrue && cd whiletrue
261
+ direnv allow # or: devenv shell
262
+ poe check # format check, lint, pyright, tests + coverage, docs check
263
+ whiletrue --help # installed editable into .devenv/state/venv
264
+ ```
265
+
266
+ Live tests against real agent CLIs are opt-in: `WHILETRUE_LIVE=1 uv run pytest tests/live -v`.
267
+
268
+ ## Recursive self-improvement
269
+
270
+ Optional and off by default: `rsi: true` lets whiletrue improve the harness around your agent (prompts, skills, subagents) item by item with the Propose, Probe, Compose method from Harness², using isolated rollouts, blind selection and a per-domain experience library. A person approves what is adopted. It multiplies agent spend (about 7 times at `k: 1`) and is capped by `budget_usd`. See [docs/rsi.md](docs/rsi.md). Next: Gemini CLI support.
271
+
272
+ <img src="docs/assets/rsi-architecture.svg" alt="rsi architecture: task-level recursion per item (reference rollouts, propose, INV and DOM candidates, compose, blind selection, apply) and harnessing-level recursion across items (reflect, human adoption, experience library)" width="900">
273
+
274
+ ## Acknowledgements and citation
275
+
276
+ The `rsi` feature builds on **Harness²: Recursive Agent Harnessing for an Open World** (Xu et al., Google Research, 2026; [arXiv:2610.14224](https://arxiv.org/abs/2610.14224), [code](https://github.com/google-research/harness2), Apache-2.0). If you use `rsi` in research, please cite the paper (BibTeX in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)). whiletrue is an independent project, not affiliated with Google or the Harness² authors.
277
+
278
+ ## License
279
+
280
+ MIT. See [LICENSE](LICENSE). Third-party code under `third_party/`, benchmarks, and datasets retain their upstream licenses; see [third-party notices](THIRD_PARTY_NOTICES.md).
@@ -0,0 +1,253 @@
1
+ <div align="center">
2
+
3
+ <img src="docs/assets/logo.svg" alt="whiletrue logo" width="96" height="96">
4
+
5
+ # whiletrue
6
+
7
+ **The loop around your coding agents.**
8
+
9
+ Run pipelines of agentic and deterministic steps around Claude Code, opencode and Codex, locally, with gates, humans in the loop, and crash-safe resume.
10
+
11
+ [![PyPI](https://img.shields.io/pypi/v/whiletrue?logo=pypi&logoColor=white)](https://pypi.org/project/whiletrue/)
12
+ [![Python](https://img.shields.io/pypi/pyversions/whiletrue?logo=python&logoColor=white)](https://pypi.org/project/whiletrue/)
13
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
14
+ [![Docs](https://img.shields.io/badge/docs-docs%2F-informational)](docs/README.md)
15
+
16
+ </div>
17
+
18
+ > LangGraph builds the agent; whiletrue runs the loop around agents you already have.
19
+
20
+ <div align="center">
21
+
22
+ <img src="docs/assets/demo-real.svg" alt="Recording of a real run: two Claude Code agents work in parallel in tmux panes while a control panel and shell show status, both items pass their pytest gate and park for human approval, then approve and resume finish them" width="900">
23
+
24
+ <sub>A real run, not a mock-up: two Claude Code agents in parallel, a pytest gate, a human approval and a resume, about $0.23 in total. Captured from the live tmux panes; the two tmux windows are drawn side by side.</sub>
25
+
26
+ </div>
27
+
28
+ ```bash
29
+ uvx whiletrue init # scaffold a Ralph loop
30
+ uvx whiletrue run # agent -> pytest gate -> repeat until green
31
+ ```
32
+
33
+ ## Overview
34
+
35
+ Coding agents are good at one task and bad at finishing a backlog unattended. whiletrue is the orchestrator you put around them. You describe the loop in a single `whiletrue.yaml`: which agent does the work, which deterministic gate checks it, when to retry, when to ask a person. whiletrue validates the config before spending a token, runs it, and records every step so you can inspect, replay or resume it.
36
+
37
+ - **Pipelines, not prompts.** Agent steps, shell and git steps, and gates compose with `sequence`, `loop`, `map`, `parallel`, `switch`, `retry`, `try` and `human.approve`. Every loop is bounded.
38
+ - **Any backend.** `claude-code-headless`, `claude-code` (the real interactive CLI in a tmux pane you can type into), `opencode` and `codex`. Mix them in one pipeline.
39
+ - **Many items at once.** One item per task or GitHub issue, each in its own git worktree, with `parallel: N` and a cap on live agent sessions.
40
+ - **Humans in the loop.** A gate parks an item until a person approves, rejects or comments; other items keep running. Every review comment gets an answer.
41
+ - **Durable.** State lives in SQLite. Kill the process at any point and `whiletrue resume` replays finished steps instead of redoing them; side effects (PRs, merges, replies) happen exactly once.
42
+ - **Local.** One machine, no server, no account. Everything is a file in your repo plus `.whiletrue/`.
43
+
44
+ ## Contents
45
+
46
+ - [Install](#install)
47
+ - [Quickstart](#quickstart)
48
+ - [Architecture](#architecture)
49
+ - [Concepts](#concepts)
50
+ - [Examples](#examples)
51
+ - [Backends](#backends)
52
+ - [CLI](#cli)
53
+ - [Documentation](#documentation)
54
+ - [Development](#development)
55
+ - [License](#license)
56
+
57
+ ## Install
58
+
59
+ Requires Python 3.12+ and at least one agent CLI on your `PATH` ([Claude Code](https://claude.com/claude-code), [opencode](https://opencode.ai) or [Codex](https://github.com/openai/codex)). `git` is needed for worktrees, `tmux` for interactive agents, and `gh` for the GitHub integration.
60
+
61
+ ```bash
62
+ uv tool install whiletrue # or: pip install whiletrue
63
+ whiletrue --help
64
+
65
+ uvx whiletrue --help # or run it without installing
66
+ ```
67
+
68
+ If an agent CLI is not on `PATH`, set `WHILETRUE_CLAUDE_BIN`, `WHILETRUE_OPENCODE_BIN` or `WHILETRUE_CODEX_BIN`.
69
+
70
+ ## Quickstart
71
+
72
+ ```bash
73
+ cd my-project
74
+ whiletrue init # writes whiletrue.yaml and agents/ralph.md
75
+ whiletrue validate # config, wiring, limits and safety rules; spends nothing
76
+ whiletrue plan # prints the expanded step tree; spends nothing
77
+ whiletrue run # runs it
78
+ whiletrue status # steps, outcomes and cost of the latest run
79
+ ```
80
+
81
+ The scaffold is a Ralph loop. The agent runs in a fresh context, a deterministic `pytest` gate checks the result, and the loop repeats (at most 5 times) until the gate is green:
82
+
83
+ ```yaml
84
+ # whiletrue.yaml
85
+ name: ralph
86
+ pipeline:
87
+ loop:
88
+ max: 5 # every loop is bounded; `max: unbounded` is an explicit opt-out
89
+ do:
90
+ - agent: { uses: ./agents/ralph.md }
91
+ - gate.shell: { run: "pytest" }
92
+ ```
93
+
94
+ ```markdown
95
+ ---
96
+ # agents/ralph.md
97
+ agent: ralph
98
+ runner: claude-code-headless
99
+ permission_mode: acceptEdits
100
+ tools: [Read, Edit, Write, "Bash(pytest*)", "Bash(git *)"]
101
+ limits: { budget_usd: 2, turns: 40, wall: 20m }
102
+ ---
103
+ Work through the next unfinished item in TODO.md. Make the tests pass.
104
+
105
+ Failure output from the previous attempt (empty on the first try):
106
+ {{iter.previous}}
107
+ ```
108
+
109
+ Every agent must declare `limits`; `validate` refuses the config otherwise.
110
+
111
+ ## Architecture
112
+
113
+ <img src="docs/assets/architecture.svg" alt="Architecture: whiletrue.yaml and the CLI drive the core engine (loader, scheduler, pipeline runtime, park and resume, plugin registry, SQLite store); built-in plugins connect it to agent CLIs, git, GitHub and tmux" width="900">
114
+
115
+ The core knows nothing about git, GitHub, tmux or any agent. Every integration is a plugin built on the public plugin API, including the optional `rsi` layer, so you can add your own ([plugins](docs/plugins.md), [architecture](docs/architecture.md)).
116
+
117
+ ## Concepts
118
+
119
+ | Concept | What it is |
120
+ | --- | --- |
121
+ | **Pipeline** | A list of steps, or one strategy, in `whiletrue.yaml`. |
122
+ | **Step** | An action: `agent`, a shell command, a git or GitHub operation, a gate. Pure, deterministic, agentic or side-effecting. |
123
+ | **Strategy** | Control flow over steps: `sequence`, `tap`, `loop`, `map`, `parallel`, `switch`, `retry`, `try`, `human.approve`. |
124
+ | **Outcome ports** | Every step ends on `ok`, `fail`, `needs_human`, `skip` or `rejected`. `wires:` routes a port to another step; back-wires make loops. |
125
+ | **Item** | One unit of work from a `source:` (`json`, `markdown_tasks`, `github_issues`). Items run in parallel, in dependency order. |
126
+ | **Workspace** | Per-item checkout: `git-worktree`, `dir-copy` or `none`. |
127
+ | **Gate** | A deterministic check, or a human decision, that an item must pass. |
128
+ | **Recipe** | A ready-made composite: `ralph`, `review-pass`, `review-respond`, `issue-loop`. |
129
+ | **Run record** | The SQLite log of steps, parks, effects, comments and cost that makes replay and resume possible. |
130
+
131
+ Details: [reference](docs/reference.md), [authoring guide](docs/authoring.md), [architecture](docs/architecture.md).
132
+
133
+ ## Examples
134
+
135
+ ### A Ralph loop
136
+
137
+ <img src="docs/assets/ralph-loop.svg" alt="Ralph loop: agent in a fresh context, then a pytest gate; green ends the loop, red feeds the output back to the agent" width="900">
138
+
139
+ This is what `whiletrue init` scaffolds. See the YAML under [Quickstart](#quickstart).
140
+
141
+ ### Review loop with a read-only reviewer
142
+
143
+ ```yaml
144
+ pipeline:
145
+ composite:
146
+ uses: "recipe:review-pass"
147
+ params: { reviewer: ./agents/review.md, fixer: ./agents/fix.md, max_rounds: 3 }
148
+ ```
149
+
150
+ ### A backlog in parallel worktrees
151
+
152
+ ```yaml
153
+ parallel: 4
154
+ max_agents: 4
155
+ source: { markdown_tasks: { path: TASKS.md } } # - [ ] Title {#id after=other}
156
+ workspace: { git-worktree: { branch: "wt/{{item.id}}" } }
157
+ pipeline:
158
+ loop:
159
+ max: 5
160
+ do:
161
+ - agent: { uses: ./agents/implement.md }
162
+ - gate.shell: { run: "pytest" }
163
+ ```
164
+
165
+ ### A human gate on a pull request
166
+
167
+ ```yaml
168
+ - id: review
169
+ human.approve:
170
+ what: pr
171
+ wake: { any: [cli, { github.pr_review: any }] }
172
+ do:
173
+ - composite: { uses: "recipe:review-respond", params: { responder: ./agents/respond.md } }
174
+ wires: { rejected: fix }
175
+ ```
176
+
177
+ ```bash
178
+ whiletrue run # parks at the gate and exits with code 2
179
+ whiletrue status # lists what is waiting
180
+ whiletrue approve 12 # or: reject 12 --note "what to change"
181
+ whiletrue resume # finished steps are replayed, never redone
182
+ ```
183
+
184
+ ### The reference pipeline: issues with a human in the loop
185
+
186
+ [`examples/issue-loop`](examples/issue-loop/README.md) takes every issue in a GitHub milestone from open to merged: implement in a worktree, run the gate, open a PR, answer review comments, merge, close. You review every PR, and every comment you leave gets an answer.
187
+
188
+ <img src="docs/assets/issue-loop.svg" alt="Issue loop flow: implement with retry and a gate, open a PR, a human review gate with comment replies and a fix branch on rejection, then sync, a merge approval and the merge" width="900">
189
+
190
+ ## Backends
191
+
192
+ Choose per agent with `runner:`.
193
+
194
+ | Runner | Runs | Notes |
195
+ | --- | --- | --- |
196
+ | `claude-code-headless` | `claude -p` | Default. Budget, turns and wall limits enforced. |
197
+ | `claude-code` | Interactive Claude Code in a tmux pane | Watch it, type into it (recorded as a *steer*). Submits through a bundled MCP tool and hooks. |
198
+ | `opencode` | `opencode run` | Structured output checked against the step's cap. |
199
+ | `codex` | `codex exec` | Sandbox derived from `permission_mode`. No budget enforcement. |
200
+
201
+ Structured `outputs:` work on all of them. See [choosing a backend](docs/authoring.md#choosing-a-backend).
202
+
203
+ ## CLI
204
+
205
+ | Command | Purpose |
206
+ | --- | --- |
207
+ | `init`, `validate`, `plan` | Scaffold, check and preview a pipeline without spending tokens. |
208
+ | `run`, `resume`, `rerun`, `cancel` | Start, continue after a park or crash, redo, or stop items. |
209
+ | `status`, `logs`, `cost`, `replay` | Inspect runs, steps and spend; replay a recorded run. |
210
+ | `approve`, `reject`, `comment` | Decide human gates and talk to waiting items. |
211
+ | `attach`, `panel` | Open the tmux session and the live control panel. |
212
+ | `history`, `learnings` | Audit trail and approved lessons for future agents. |
213
+ | `lock` | Show or clear the run lock. |
214
+
215
+ Full reference: [docs/cli.md](docs/cli.md). New here? Follow the [tutorial](docs/tutorial.md).
216
+
217
+ ## Documentation
218
+
219
+ Start at [docs/README.md](docs/README.md).
220
+
221
+ - [Tutorial](docs/tutorial.md): from an empty folder to your own loop with gates, a reviewer, parallel tasks and a human approval.
222
+ - [Getting started](docs/getting-started.md): a longer walkthrough, including interactive agents, gates and parallel items.
223
+ - [Authoring guide](docs/authoring.md): writing pipelines and agents.
224
+ - [Reference](docs/reference.md): every module, strategy, provider and config key.
225
+ - [CLI](docs/cli.md) and [plugins](docs/plugins.md): the command line and extending whiletrue.
226
+ - [Architecture](docs/architecture.md), [plan](docs/plan.md), [todo](docs/todo.md) and [changelog](CHANGELOG.md).
227
+
228
+ ## Development
229
+
230
+ Requires [devenv](https://devenv.sh) (or Python 3.12 + [uv](https://docs.astral.sh/uv/)). See [developing.md](docs/developing.md).
231
+
232
+ ```bash
233
+ git clone https://github.com/dariussingh/whiletrue && cd whiletrue
234
+ direnv allow # or: devenv shell
235
+ poe check # format check, lint, pyright, tests + coverage, docs check
236
+ whiletrue --help # installed editable into .devenv/state/venv
237
+ ```
238
+
239
+ Live tests against real agent CLIs are opt-in: `WHILETRUE_LIVE=1 uv run pytest tests/live -v`.
240
+
241
+ ## Recursive self-improvement
242
+
243
+ Optional and off by default: `rsi: true` lets whiletrue improve the harness around your agent (prompts, skills, subagents) item by item with the Propose, Probe, Compose method from Harness², using isolated rollouts, blind selection and a per-domain experience library. A person approves what is adopted. It multiplies agent spend (about 7 times at `k: 1`) and is capped by `budget_usd`. See [docs/rsi.md](docs/rsi.md). Next: Gemini CLI support.
244
+
245
+ <img src="docs/assets/rsi-architecture.svg" alt="rsi architecture: task-level recursion per item (reference rollouts, propose, INV and DOM candidates, compose, blind selection, apply) and harnessing-level recursion across items (reflect, human adoption, experience library)" width="900">
246
+
247
+ ## Acknowledgements and citation
248
+
249
+ The `rsi` feature builds on **Harness²: Recursive Agent Harnessing for an Open World** (Xu et al., Google Research, 2026; [arXiv:2610.14224](https://arxiv.org/abs/2610.14224), [code](https://github.com/google-research/harness2), Apache-2.0). If you use `rsi` in research, please cite the paper (BibTeX in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)). whiletrue is an independent project, not affiliated with Google or the Harness² authors.
250
+
251
+ ## License
252
+
253
+ MIT. See [LICENSE](LICENSE). Third-party code under `third_party/`, benchmarks, and datasets retain their upstream licenses; see [third-party notices](THIRD_PARTY_NOTICES.md).
@@ -0,0 +1,32 @@
1
+ # Third-party notices
2
+
3
+ whiletrue is MIT licensed (see [LICENSE](LICENSE)). Third-party code under `third_party/`, benchmarks and datasets retain their upstream licenses.
4
+
5
+ ## Harness²
6
+
7
+ The `rsi` feature builds on **Harness²: Recursive Agent Harnessing for an Open World** (Xu et al., Google Research, 2026; [arXiv:2610.14224](https://arxiv.org/abs/2610.14224), [code](https://github.com/google-research/harness2), Apache-2.0). If you use `rsi` in research, please cite the paper (BibTeX below). whiletrue is an independent project, not affiliated with Google or the Harness² authors.
8
+
9
+ The optional recursive self-improvement feature (`rsi`) is built on the method and code of Harness² by Google Research. The method code is ported and refactored into this repository as `whiletrue.rsi.harness2`; users install no extra dependency.
10
+
11
+ - Source: https://github.com/google-research/harness2 (pinned commit `1cfe254e8d25b15f37048c3730134686abe60335`)
12
+ - License: Apache License 2.0. The license text is at [third_party/harness2/LICENSE](third_party/harness2/LICENSE).
13
+ - Copyright 2026 Google LLC.
14
+ - Each ported file in `whiletrue/rsi/harness2/` keeps its upstream copyright header and carries a notice that it was modified. The files, their upstream paths and the modifications are listed in [third_party/harness2/PROVENANCE.md](third_party/harness2/PROVENANCE.md). Those files are licensed under Apache-2.0, not MIT.
15
+ - Not taken: the benchmark runners, patches and datasets in the upstream repository (JobBench, LAB, WorkBuddy-Bench). They have their own licenses, and the WorkBuddy-derived code includes a territorial limitation on use. whiletrue does not copy, bundle or redistribute them.
16
+
17
+ Please cite the paper if you use `rsi` in research:
18
+
19
+ ```bibtex
20
+ @misc{xu2026harness2,
21
+ title = {Harness$^2$: Recursive Agent Harnessing for an Open World},
22
+ author = {Xu, Ruiyao and Chen, Yanfei and CuiZhu, Zhongying and Dalvi Mishra, Bhavana and Ming, Yifei and Yu, Han and Han, Rujun and Lee, Chen-Yu and Pfister, Tomas},
23
+ year = {2026},
24
+ eprint = {2610.14224},
25
+ archivePrefix = {arXiv},
26
+ primaryClass = {cs.AI},
27
+ doi = {10.48550/arXiv.2610.14224},
28
+ url = {https://arxiv.org/abs/2610.14224}
29
+ }
30
+ ```
31
+
32
+ whiletrue is an independent project. It is not affiliated with or endorsed by Google or the Harness² authors.
@@ -4,14 +4,18 @@
4
4
  | -------------------------------------- | --------------------------------------------------------------------------------- |
5
5
  | [architecture.md](architecture.md) | Full design: core model, runtime, state, agents, human gates, packages |
6
6
  | [getting-started.md](getting-started.md) | User guide: install, first loop, commands, exit codes, safety defaults |
7
+ | [tutorial.md](tutorial.md) | Tutorial: install, first loop, then build your own gates, review, parallel and human steps |
7
8
  | [authoring.md](authoring.md) | Authoring guide: pipelines, composites, agents, choosing a backend |
8
9
  | [cli.md](cli.md) | CLI reference: every command, option, exit code and environment variable |
10
+ | [rsi.md](rsi.md) | Recursive self-improvement: turn it on, what it costs, adoption, limits |
9
11
  | [reference.md](reference.md) | User reference: modules, control flow, expressions, composites, recipes, replay |
10
12
  | [plugins.md](plugins.md) | Extending whiletrue: modules, strategies, runners, caps, entry points |
11
13
  | [developing.md](developing.md) | Contributing: setup, layout, run flow, workflow |
14
+ | [rsi-plan.md](rsi-plan.md) | Execution plan for M5: Harness² recursive self-improvement and the Gemini CLI backend |
12
15
  | [plan.md](plan.md) | Implementation plan: milestones M0–M4, dependencies, exit criteria, risks, spikes |
13
16
  | [todo.md](todo.md) | Numbered, ordered implementation checklist (work top to bottom) |
14
17
  | [open-questions.md](open-questions.md) | Undecided design questions, each tied to the milestone that forces the decision |
18
+ | [spike-rsi.md](spike-rsi.md) | Findings: Harness² method, what is ported, concept mapping and decisions |
15
19
  | [spike-interactive.md](spike-interactive.md) | Findings: plugin hooks and MCP in interactive Claude Code (OQ-1) |
16
20
  | [conventions.md](conventions.md) | Engineering conventions, test and docs rules (the non-negotiables made concrete) |
17
21