loop-engineer 0.10.0__tar.gz → 0.11.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 (380) hide show
  1. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.claude-plugin/plugin.json +1 -1
  2. loop_engineer-0.11.0/.github/workflows/ci.yml +243 -0
  3. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/workflows/publish.yml +1 -1
  4. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/CHANGELOG.md +47 -0
  5. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/PKG-INFO +14 -6
  6. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/README.md +13 -5
  7. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/action.yml +1 -1
  8. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/gap-reports/scoreboard.md +14 -3
  9. loop_engineer-0.11.0/docs/integrations/openhands.md +118 -0
  10. loop_engineer-0.11.0/docs/integrations/ruflo.md +146 -0
  11. loop_engineer-0.11.0/docs/superpowers/plans/2026-07-24-event-chain-tamper-evident-provenance.md +1502 -0
  12. loop_engineer-0.11.0/docs/superpowers/plans/2026-07-25-slice2-verifier-identity-independence.md +1906 -0
  13. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st3-integration-adapters.md +62 -14
  14. loop_engineer-0.11.0/examples/openhands-certify/README.md +85 -0
  15. loop_engineer-0.11.0/examples/openhands-certify/certify_run.py +176 -0
  16. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/blocked/base_state.json +54 -0
  17. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/blocked/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
  18. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/blocked/events/event-00001-b1c2d3e4-0000-4000-8000-00000000ab02.json +9 -0
  19. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/finished/base_state.json +47 -0
  20. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/finished/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +14 -0
  21. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/max-iterations/base_state.json +54 -0
  22. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/max-iterations/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
  23. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/max-iterations/events/event-00001-b1c2d3e4-0000-4000-8000-00000000ab01.json +9 -0
  24. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/paused/base_state.json +54 -0
  25. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/paused/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
  26. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/running/base_state.json +54 -0
  27. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/running/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
  28. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/stuck/base_state.json +54 -0
  29. loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/stuck/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
  30. loop_engineer-0.11.0/examples/openhands-certify/fixtures/workspaces/green/artifact.txt +1 -0
  31. loop_engineer-0.11.0/examples/openhands-certify/fixtures/workspaces/stale/artifact.txt +1 -0
  32. loop_engineer-0.11.0/examples/ruflo-gate/README.md +82 -0
  33. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.claude-flow/metrics/v3-progress.json +20 -0
  34. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.hive-mind/sessions/hive-mind-prompt-swarm-2026-07-25.txt +13 -0
  35. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-coder-02.json +12 -0
  36. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-coder-03.json +12 -0
  37. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-queen-01.json +12 -0
  38. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-reviewer-04.json +12 -0
  39. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/coordination/consensus-2026-07-25T09-31-52Z.json +17 -0
  40. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/memory-export.json +48 -0
  41. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/state.json +9 -0
  42. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-001-spec.json +9 -0
  43. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-002-implement.json +9 -0
  44. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-003-logging.json +9 -0
  45. loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-004-review.json +9 -0
  46. loop_engineer-0.11.0/examples/ruflo-gate/fixture/dedupe-report.json +10 -0
  47. loop_engineer-0.11.0/examples/ruflo-gate/fixture/dedupe.log +16 -0
  48. loop_engineer-0.11.0/examples/ruflo-gate/fixture/src/import_contacts.py +24 -0
  49. loop_engineer-0.11.0/examples/ruflo-gate/swarm_example.py +321 -0
  50. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/__main__.py +29 -1
  51. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/completion.py +22 -3
  52. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/contract.py +344 -3
  53. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/emit.py +204 -2
  54. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/events.py +19 -7
  55. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/evidence.py +148 -10
  56. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/integrations.py +8 -0
  57. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/paths.py +7 -0
  58. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/reducer.py +26 -1
  59. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/runner.py +112 -8
  60. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/runtime.py +134 -13
  61. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/simulate.py +4 -7
  62. loop_engineer-0.11.0/loop/verifier.py +148 -0
  63. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/pyproject.toml +1 -1
  64. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/repo-os-contract.md +482 -16
  65. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/safety-and-approvals.md +4 -0
  66. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/event.schema.json +3 -3
  67. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/evidence.schema.json +16 -3
  68. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/tasks.schema.json +5 -1
  69. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/terminal.schema.json +4 -1
  70. loop_engineer-0.11.0/scripts/ci_anchor_probe.py +83 -0
  71. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/metrics.py +29 -3
  72. loop_engineer-0.11.0/scripts/test_adversarial_evidence_binding.py +540 -0
  73. loop_engineer-0.11.0/scripts/test_adversarial_verifier_identity.py +268 -0
  74. loop_engineer-0.11.0/scripts/test_bound_artifact_view.py +233 -0
  75. loop_engineer-0.11.0/scripts/test_ci_anchor_probe.py +53 -0
  76. loop_engineer-0.11.0/scripts/test_completion_verdict.py +258 -0
  77. loop_engineer-0.11.0/scripts/test_completion_verified_evidence.py +366 -0
  78. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_conformance.py +141 -0
  79. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_version.py +2 -2
  80. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_doctor_eventstore.py +106 -2
  81. loop_engineer-0.11.0/scripts/test_doctor_evidence.py +147 -0
  82. loop_engineer-0.11.0/scripts/test_doctor_evidence_binding.py +189 -0
  83. loop_engineer-0.11.0/scripts/test_doctor_evidence_verification.py +211 -0
  84. loop_engineer-0.11.0/scripts/test_doctor_store_read_guard.py +55 -0
  85. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_event_chain.py +125 -2
  86. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_evidence.py +103 -1
  87. loop_engineer-0.11.0/scripts/test_evidence_binding_runner.py +139 -0
  88. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_cli.py +1 -1
  89. loop_engineer-0.11.0/scripts/test_metrics_verifier_source.py +100 -0
  90. loop_engineer-0.11.0/scripts/test_openhands_recipe.py +205 -0
  91. loop_engineer-0.11.0/scripts/test_openhands_sdk_drift.py +75 -0
  92. loop_engineer-0.11.0/scripts/test_ruflo_recipe.py +199 -0
  93. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_runner_dispatch.py +111 -1
  94. loop_engineer-0.11.0/scripts/test_verifier_identity.py +180 -0
  95. loop_engineer-0.11.0/scripts/test_verify_evidence_object_collision.py +67 -0
  96. loop_engineer-0.11.0/scripts/test_verify_evidence_objects.py +150 -0
  97. loop_engineer-0.11.0/scripts/test_verify_evidence_writer.py +185 -0
  98. loop_engineer-0.10.0/.github/workflows/ci.yml +0 -113
  99. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.claude-plugin/marketplace.json +0 -0
  100. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  101. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  102. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  103. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  104. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/dependabot.yml +0 -0
  105. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.gitignore +0 -0
  106. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.pre-commit-hooks.yaml +0 -0
  107. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/CODE_OF_CONDUCT.md +0 -0
  108. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/CONTRIBUTING.md +0 -0
  109. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/GLOSSARY.md +0 -0
  110. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/LICENSE +0 -0
  111. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/SECURITY.md +0 -0
  112. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/ROADMAP-v1.0.md +0 -0
  113. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/adr/0001-proof-kernel-and-runtime.md +0 -0
  114. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/01-good-first-qw9-trigger-phrases.md +0 -0
  115. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/02-good-first-qw10-self-eval-labels.md +0 -0
  116. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/03-good-first-emit-metrics-vocabulary.md +0 -0
  117. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/04-help-wanted-openhands-recipe.md +0 -0
  118. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/05-help-wanted-ruflo-recipe.md +0 -0
  119. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/06-help-wanted-gap-reports.md +0 -0
  120. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/07-help-wanted-emit-scaffold-runlog-seed.md +0 -0
  121. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/demo.cast +0 -0
  122. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/demo.gif +0 -0
  123. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/gap-reports/superpowers.md +0 -0
  124. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/integrations/langgraph.md +0 -0
  125. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/integrations/temporal.md +0 -0
  126. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/metrics-baseline.json +0 -0
  127. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/social-card.png +0 -0
  128. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-20-loop-engineer-v1.md +0 -0
  129. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-30-loop-engineer-v1.0-roadmap.md +0 -0
  130. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-03-adoption-slices.md +0 -0
  131. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-08-v0.8.0-composes-the-field.md +0 -0
  132. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-09-st5-harness-scoreboard.md +0 -0
  133. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-20-loop-engineer-design.md +0 -0
  134. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st1-metrics-baseline.md +0 -0
  135. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st2-portable-contract-spec.md +0 -0
  136. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-v04-credibility-enforcement.md +0 -0
  137. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-03-adoption-slices-design.md +0 -0
  138. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-08-v0.8.0-composes-the-field-design.md +0 -0
  139. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-09-st5-harness-scoreboard-design.md +0 -0
  140. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/evals/cases/structural.json +0 -0
  141. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/evals/rubric.md +0 -0
  142. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/README.md +0 -0
  143. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/mission.md +0 -0
  144. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/roadmap.md +0 -0
  145. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/plan.md +0 -0
  146. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/references.md +0 -0
  147. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/shape.md +0 -0
  148. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/standards.md +0 -0
  149. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/backend/data-imports.md +0 -0
  150. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/index.yml +0 -0
  151. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/README.md +0 -0
  152. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad/bmm/config.yaml +0 -0
  153. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/1-1-deduplicate-csv-rows.md +0 -0
  154. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/epic-1-retro-2026-07-09.md +0 -0
  155. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/sprint-status.yaml +0 -0
  156. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/epics.md +0 -0
  157. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/prd.md +0 -0
  158. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/src/import_contacts.py +0 -0
  159. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/tests/test_import_contacts.py +0 -0
  160. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235-analysis.md +0 -0
  161. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235.md +0 -0
  162. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/epic.md +0 -0
  163. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/execution-status.md +0 -0
  164. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/github-mapping.md +0 -0
  165. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/progress.md +0 -0
  166. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/stream-A.md +0 -0
  167. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/prds/csv-dedupe.md +0 -0
  168. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/README.md +0 -0
  169. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/approvals/.gitkeep +0 -0
  170. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-run.txt +0 -0
  171. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-verdict.json +0 -0
  172. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T1.json +0 -0
  173. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2-iter1.json +0 -0
  174. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2.json +0 -0
  175. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/checkpoints/.gitkeep +0 -0
  176. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/manifest.yaml +0 -0
  177. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/memory/.gitkeep +0 -0
  178. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/repair/iter-002.json +0 -0
  179. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/state.json +0 -0
  180. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/ADR.md +0 -0
  181. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/README.md +0 -0
  182. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/RUNLOG.md +0 -0
  183. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/SPEC.md +0 -0
  184. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/TASKS.json +0 -0
  185. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/WORKFLOW.md +0 -0
  186. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/run-example +0 -0
  187. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-fast +0 -0
  188. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-full +0 -0
  189. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/manifest.json +0 -0
  190. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/measure_coverage.py +0 -0
  191. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/pricing.py +0 -0
  192. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_holdout.py +0 -0
  193. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_visible.py +0 -0
  194. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/terminal_state.json +0 -0
  195. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/absolute-uri.json +0 -0
  196. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/bad-sha256-pattern.json +0 -0
  197. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/missing-required-field.json +0 -0
  198. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/scheme-uri.json +0 -0
  199. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/valid-evidence.json +0 -0
  200. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/holdout-verdict.json +0 -0
  201. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1-iter1.json +0 -0
  202. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1.json +0 -0
  203. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/manifest.yaml +0 -0
  204. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/repair/iter-002.json +0 -0
  205. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/state.json +0 -0
  206. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/terminal_state.json +0 -0
  207. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/README.md +0 -0
  208. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/RUNLOG.md +0 -0
  209. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/SPEC.md +0 -0
  210. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/TASKS.json +0 -0
  211. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/WORKFLOW.md +0 -0
  212. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/run-example +0 -0
  213. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-fast +0 -0
  214. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-full +0 -0
  215. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/jobs.py +0 -0
  216. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/manifest.json +0 -0
  217. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/measure_stability.py +0 -0
  218. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_holdout.py +0 -0
  219. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_visible.py +0 -0
  220. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/langgraph-emit/README.md +0 -0
  221. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/langgraph-emit/graph_example.py +0 -0
  222. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/naive-loop/.loop/state.json +0 -0
  223. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/naive-loop/README.md +0 -0
  224. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/README.md +0 -0
  225. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/.openspec.yaml +0 -0
  226. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/design.md +0 -0
  227. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/proposal.md +0 -0
  228. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/specs/csv-dedupe/spec.md +0 -0
  229. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/tasks.md +0 -0
  230. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/config.yaml +0 -0
  231. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/specs/csv-dedupe/spec.md +0 -0
  232. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/plans/coverage-repair.plan.json +0 -0
  233. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/plans/invalid/cyclic-dependency.plan.json +0 -0
  234. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/plans/invalid/missing-goal.plan.json +0 -0
  235. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/plans/completed/csv-dedupe.plan.md +0 -0
  236. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/prds/csv-dedupe.prd.md +0 -0
  237. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reports/csv-dedupe-report.md +0 -0
  238. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-cycle-0.verdict.json +0 -0
  239. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-review.md +0 -0
  240. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.run.log +0 -0
  241. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.state.json +0 -0
  242. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/README.md +0 -0
  243. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/swarm-activity.json +0 -0
  244. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/v3-progress.json +0 -0
  245. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/security/audit-status.json +0 -0
  246. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.hive-mind/sessions/hive-mind-prompt-swarm-2026-07-09.txt +0 -0
  247. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.mcp.json +0 -0
  248. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.swarm/memory-export.json +0 -0
  249. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/README.md +0 -0
  250. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/feature.json +0 -0
  251. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/memory/constitution.md +0 -0
  252. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/README.md +0 -0
  253. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/checklists/requirements.md +0 -0
  254. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/plan.md +0 -0
  255. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/quickstart.md +0 -0
  256. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/research.md +0 -0
  257. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/spec.md +0 -0
  258. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/tasks.md +0 -0
  259. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/.superpowers/sdd/progress.md +0 -0
  260. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/README.md +0 -0
  261. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/docs/superpowers/plans/2026-07-08-csv-dedupe.md +0 -0
  262. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/docs/superpowers/specs/2026-07-08-csv-dedupe-design.md +0 -0
  263. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/config.json +0 -0
  264. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/docs/prd.txt +0 -0
  265. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/reports/task-complexity-report.json +0 -0
  266. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/state.json +0 -0
  267. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/task_001.txt +0 -0
  268. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/tasks.json +0 -0
  269. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/templates/example_prd.txt +0 -0
  270. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/CLAUDE.md +0 -0
  271. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/README.md +0 -0
  272. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/temporal-certify/README.md +0 -0
  273. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/temporal-certify/workflow_example.py +0 -0
  274. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/hooks/stop_firewall.py +0 -0
  275. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/__init__.py +0 -0
  276. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/_resources.py +0 -0
  277. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/architect.py +0 -0
  278. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/chain.py +0 -0
  279. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/foreign.py +0 -0
  280. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/fsm.py +0 -0
  281. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/migrate.py +0 -0
  282. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/plan.py +0 -0
  283. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/runcontrol.py +0 -0
  284. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/scaffold.py +0 -0
  285. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/architecture-matrix.md +0 -0
  286. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/eval-suite.md +0 -0
  287. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/loop-patterns.md +0 -0
  288. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/model-routing.md +0 -0
  289. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/platform-map.md +0 -0
  290. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/prompt-templates.md +0 -0
  291. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/manifest.schema.json +0 -0
  292. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/plan.schema.json +0 -0
  293. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/receipt.schema.json +0 -0
  294. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/repair-record.schema.json +0 -0
  295. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/rollout-record.schema.json +0 -0
  296. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/state.schema.json +0 -0
  297. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/action_scorecard.py +0 -0
  298. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/anticheat_scan.py +0 -0
  299. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/benchmark_harness.py +0 -0
  300. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/chain_fixtures.py +0 -0
  301. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/holdout_gate.py +0 -0
  302. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/inspect_loop.py +0 -0
  303. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/rollout_ledger.py +0 -0
  304. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/runtime_monitor.py +0 -0
  305. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/self_eval.py +0 -0
  306. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_action_scorecard.py +0 -0
  307. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_adversarial_chain.py +0 -0
  308. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_adversarial_kernel.py +0 -0
  309. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_adversarial_process.py +0 -0
  310. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_anticheat_scan.py +0 -0
  311. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_benchmark_harness.py +0 -0
  312. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_ci_release_mode.py +0 -0
  313. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_completion_policy.py +0 -0
  314. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_contract_records.py +0 -0
  315. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_adoption.py +0 -0
  316. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_baseline.py +0 -0
  317. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_claims.py +0 -0
  318. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_emit.py +0 -0
  319. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_eventstore.py +0 -0
  320. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_example_runnable.py +0 -0
  321. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_flaky_example.py +0 -0
  322. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_foreign_inspect.py +0 -0
  323. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_fsm.py +0 -0
  324. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_holdout_gate.py +0 -0
  325. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_inspect_loop.py +0 -0
  326. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_integrations.py +0 -0
  327. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe.py +0 -0
  328. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe_st3.py +0 -0
  329. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_architect_cli.py +0 -0
  330. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_cli.py +0 -0
  331. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_cli_status_replay.py +0 -0
  332. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_contract_core.py +0 -0
  333. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_runcontrol_cli.py +0 -0
  334. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_zero_writes.py +0 -0
  335. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_manifest_extra_states_schema.py +0 -0
  336. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_metrics.py +0 -0
  337. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_metrics_cli.py +0 -0
  338. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_migrate_cli.py +0 -0
  339. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_plan_schema.py +0 -0
  340. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_precommit_hook.py +0 -0
  341. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_reducer.py +0 -0
  342. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_resources.py +0 -0
  343. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_rollout_ledger.py +0 -0
  344. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_runner_verifier.py +0 -0
  345. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_runtime_monitor.py +0 -0
  346. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_scaffold.py +0 -0
  347. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_schemas_metrics.py +0 -0
  348. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_self_eval.py +0 -0
  349. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_state_vocabulary.py +0 -0
  350. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_stop_firewall.py +0 -0
  351. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_template_roundtrip.py +0 -0
  352. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_temporal_recipe.py +0 -0
  353. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_validate_frontmatter.py +0 -0
  354. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_wheel_selfcontained.py +0 -0
  355. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/validate_frontmatter.py +0 -0
  356. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-architect/SKILL.md +0 -0
  357. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-contract/SKILL.md +0 -0
  358. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-engineer/SKILL.md +0 -0
  359. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-evals/SKILL.md +0 -0
  360. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-flywheel/SKILL.md +0 -0
  361. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-inspector/SKILL.md +0 -0
  362. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-inspector/reference/patterns.md +0 -0
  363. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-repair/SKILL.md +0 -0
  364. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-run/SKILL.md +0 -0
  365. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/SKILL.md +0 -0
  366. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/reference/patterns.md +0 -0
  367. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/AGENTS.md.tmpl +0 -0
  368. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/EVALS-rubric.md.tmpl +0 -0
  369. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/RUNLOG.md.tmpl +0 -0
  370. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/SPEC.md.tmpl +0 -0
  371. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/TASKS.json.tmpl +0 -0
  372. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/WORKFLOW.md.tmpl +0 -0
  373. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/extract-trace-metrics.sh +0 -0
  374. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/judge-rubric.sh +0 -0
  375. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/manifest.yaml.tmpl +0 -0
  376. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/state.json.tmpl +0 -0
  377. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/terminal_state.json.tmpl +0 -0
  378. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/verify-fast.sh +0 -0
  379. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/verify-full.sh +0 -0
  380. {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/verify-safety.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loop-engineer",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Design, launch, verify, repair, and improve agent loops. A Claude-Code-native architect+operator for long-running, verifiable, self-improving agentic-coding systems.",
5
5
  "author": {
6
6
  "name": "Sollan Systems",
@@ -0,0 +1,243 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ gates:
13
+ name: gates (py${{ matrix.python-version }})
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ python-version: ["3.10", "3.11", "3.12"]
19
+ steps:
20
+ - uses: actions/checkout@v7
21
+
22
+ - uses: actions/setup-python@v7
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install gate dependencies
27
+ run: python -m pip install --upgrade pip pyyaml pytest jsonschema hypothesis
28
+
29
+ - name: Frontmatter gate
30
+ run: python -B scripts/validate_frontmatter.py
31
+
32
+ - name: Structural self-eval gate
33
+ run: python -B scripts/self_eval.py
34
+
35
+ - name: Test suite
36
+ run: python -B -m pytest -q -p no:cacheprovider scripts
37
+
38
+ - name: Compile portable core
39
+ run: python -B -m py_compile loop/*.py scripts/*.py
40
+
41
+ - name: Manifests and schemas are valid JSON
42
+ run: |
43
+ python -B -c "import json, glob; \
44
+ files = ['.claude-plugin/plugin.json', '.claude-plugin/marketplace.json'] \
45
+ + glob.glob('schemas/*.json') + glob.glob('evals/**/*.json', recursive=True); \
46
+ [json.load(open(f)) for f in files]; \
47
+ print(f'valid JSON: {len(files)} files')"
48
+
49
+ - name: Quickstart smoke test
50
+ run: |
51
+ python -B -m loop doctor --mode release examples/coverage-repair
52
+ python -B -m loop inspect examples/coverage-repair
53
+
54
+ - name: Plan lint smoke test
55
+ run: |
56
+ python -B -m loop plan-lint --mode release examples/plans/coverage-repair.plan.json
57
+ if python -B -m loop plan-lint --mode release examples/plans/invalid/cyclic-dependency.plan.json; then
58
+ echo "::error::cyclic-dependency.plan.json unexpectedly passed plan-lint"
59
+ exit 1
60
+ fi
61
+ if python -B -m loop plan-lint --mode release examples/plans/invalid/missing-goal.plan.json; then
62
+ echo "::error::missing-goal.plan.json unexpectedly passed plan-lint"
63
+ exit 1
64
+ fi
65
+
66
+ recipe-langgraph:
67
+ name: recipe (langgraph)
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v7
71
+ - uses: actions/setup-python@v7
72
+ with:
73
+ python-version: "3.12"
74
+ - name: Install recipe dependencies
75
+ run: python -m pip install --upgrade pip pyyaml pytest jsonschema langgraph
76
+ - name: LangGraph recipe end-to-end
77
+ run: python -B -m pytest -q -p no:cacheprovider scripts/test_langgraph_recipe.py scripts/test_langgraph_recipe_st3.py
78
+
79
+ recipe-temporal:
80
+ name: recipe (temporal)
81
+ runs-on: ubuntu-latest
82
+ steps:
83
+ - uses: actions/checkout@v7
84
+ - uses: actions/setup-python@v7
85
+ with:
86
+ python-version: "3.12"
87
+ - name: Install recipe dependencies
88
+ run: python -m pip install --upgrade pip pyyaml pytest jsonschema temporalio
89
+ - name: Temporal recipe end-to-end
90
+ # start_local() downloads the Temporal dev-server binary (~20MB) to
91
+ # $TMPDIR/temporal-sdk-python-<version> — ephemeral and quick, so (like
92
+ # recipe-langgraph) this job carries no cache step.
93
+ run: python -B -m pytest -q -p no:cacheprovider scripts/test_temporal_recipe.py
94
+
95
+ anchor-live:
96
+ name: chain anchor (live end-to-end)
97
+ runs-on: ubuntu-latest
98
+ # action-dogfood gates a store-free example, so the anchor surface — the
99
+ # --expect-chain-head gate and the action's chain-head output — has no live
100
+ # cover there. This job seeds a chained store and pins both verdicts.
101
+ env:
102
+ WRONG_HEAD: "0000000000000000000000000000000000000000000000000000000000000000"
103
+ steps:
104
+ - uses: actions/checkout@v7
105
+
106
+ - uses: actions/setup-python@v7
107
+ with:
108
+ python-version: "3.12"
109
+
110
+ - name: Install probe dependencies
111
+ # jsonschema so the probe's own doctor gate is as strict as the action's.
112
+ run: python -m pip install --upgrade pip pyyaml jsonschema
113
+
114
+ - name: Seed a chained workspace
115
+ id: seed
116
+ run: |
117
+ workspace="${RUNNER_TEMP}/anchor-ws"
118
+ head="$(python -B scripts/ci_anchor_probe.py "$workspace")"
119
+ echo "head=$head" >> "$GITHUB_OUTPUT"
120
+ echo "workspace=$workspace" >> "$GITHUB_OUTPUT"
121
+
122
+ - name: doctor accepts the seeded anchor
123
+ env:
124
+ ANCHOR_WS: ${{ steps.seed.outputs.workspace }}
125
+ ANCHOR_HEAD: ${{ steps.seed.outputs.head }}
126
+ run: python -B -m loop doctor --expect-chain-head "$ANCHOR_HEAD" "$ANCHOR_WS"
127
+
128
+ - name: doctor rejects a wrong anchor
129
+ env:
130
+ ANCHOR_WS: ${{ steps.seed.outputs.workspace }}
131
+ run: |
132
+ # Inverted so an unexpected PASS fails the job. 1 is doctor's
133
+ # report-not-ok code; 2 means the flag itself was refused, which would
134
+ # prove nothing about the anchor comparison — so pin 1 exactly.
135
+ set +e
136
+ out="$(python -B -m loop doctor --expect-chain-head "$WRONG_HEAD" "$ANCHOR_WS" 2>&1)"
137
+ status=$?
138
+ set -e
139
+ if [ "$status" -ne 1 ]; then
140
+ echo "::error::doctor exited $status on a wrong anchor; expected 1"
141
+ echo "$out"
142
+ exit 1
143
+ fi
144
+ case "$out" in
145
+ *chain_anchor_mismatch*) ;;
146
+ *) echo "::error::doctor did not report chain_anchor_mismatch"; echo "$out"; exit 1 ;;
147
+ esac
148
+
149
+ - name: Action gate with the seeded anchor
150
+ id: gate
151
+ uses: ./
152
+ with:
153
+ path: ${{ steps.seed.outputs.workspace }}
154
+ expect-chain-head: ${{ steps.seed.outputs.head }}
155
+ # 0 keeps inspect warn-only: the scaffold's advisory score must never
156
+ # be able to flake the anchor verdict this job exists to pin.
157
+ fail-under-score: "0"
158
+
159
+ - name: Action emitted the seeded head
160
+ env:
161
+ GATE_HEAD: ${{ steps.gate.outputs.chain-head }}
162
+ SEED_HEAD: ${{ steps.seed.outputs.head }}
163
+ run: |
164
+ if [ "$GATE_HEAD" != "$SEED_HEAD" ]; then
165
+ echo "::error::action chain-head output '$GATE_HEAD' != seeded head '$SEED_HEAD'"
166
+ exit 1
167
+ fi
168
+
169
+ - name: Action gate with a wrong anchor
170
+ id: gate-mismatch
171
+ continue-on-error: true
172
+ uses: ./
173
+ with:
174
+ path: ${{ steps.seed.outputs.workspace }}
175
+ expect-chain-head: ${{ env.WRONG_HEAD }}
176
+ fail-under-score: "0"
177
+
178
+ - name: Wrong anchor failed the gate and still recorded the head
179
+ env:
180
+ GATE_OUTCOME: ${{ steps.gate-mismatch.outcome }}
181
+ GATE_HEAD: ${{ steps.gate-mismatch.outputs.chain-head }}
182
+ SEED_HEAD: ${{ steps.seed.outputs.head }}
183
+ run: |
184
+ if [ "$GATE_OUTCOME" != "failure" ]; then
185
+ echo "::error::a wrong anchor did not fail the action (outcome: $GATE_OUTCOME)"
186
+ exit 1
187
+ fi
188
+ if [ "$GATE_HEAD" != "$SEED_HEAD" ]; then
189
+ echo "::error::the always-run anchor step recorded '$GATE_HEAD', not the observed head"
190
+ exit 1
191
+ fi
192
+ recipe-openhands:
193
+ name: recipe (openhands)
194
+ runs-on: ubuntu-latest
195
+ steps:
196
+ - uses: actions/checkout@v7
197
+ - uses: actions/setup-python@v6
198
+ with:
199
+ # openhands-sdk requires >=3.12; the certifier itself is stdlib-only, so
200
+ # its behavioural e2e already runs on the whole gates matrix.
201
+ python-version: "3.12"
202
+ - name: Install recipe dependencies
203
+ run: python -m pip install --upgrade pip pyyaml pytest jsonschema openhands-sdk==1.37.1 openhands-tools==1.37.1
204
+ - name: OpenHands schema-drift alarm
205
+ run: python -B -m pytest -q -p no:cacheprovider scripts/test_openhands_sdk_drift.py scripts/test_openhands_recipe.py
206
+
207
+ action-dogfood:
208
+ name: action (dogfood on flagship example)
209
+ runs-on: ubuntu-latest
210
+ steps:
211
+ - uses: actions/checkout@v7
212
+ # The repo root's live .loop/ is gitignored, so it does not exist in a fresh
213
+ # CI checkout — the tracked flagship example is the contract the action gates
214
+ # (doctor-clean, inspect 90/strong in the action's dependency-free install).
215
+ - uses: ./
216
+ with:
217
+ path: "examples/coverage-repair"
218
+ fail-under-score: "90"
219
+
220
+ - name: pre-commit consumer fixture
221
+ # bare `python` is on PATH here because the preceding `uses: ./` composite step ran setup-python
222
+ # (persisted via GITHUB_PATH) — keep the action step before this one.
223
+ run: |
224
+ python -m pip install --quiet pre-commit pytest pyyaml
225
+ python -B -m pytest -q -p no:cacheprovider scripts/test_precommit_hook.py
226
+
227
+ recipe-ruflo:
228
+ name: recipe (ruflo)
229
+ runs-on: ubuntu-latest
230
+ steps:
231
+ - uses: actions/checkout@v7
232
+ - uses: actions/setup-python@v6
233
+ with:
234
+ python-version: "3.12"
235
+ - name: Install recipe dependencies
236
+ # No npm, no Node, no credentials: ruflo has no Python package, and a live
237
+ # swarm needs the `claude` binary plus model spend. The example replays the
238
+ # committed examples/ruflo-gate/fixture/ recording instead — the gate,
239
+ # projection, emit, doctor and metrics path all still execute for real.
240
+ # The opt-in live schema-drift alarm (LOOP_RUFLO_LIVE=1) stays skipped here.
241
+ run: python -m pip install --upgrade pip pyyaml pytest jsonschema
242
+ - name: ruflo recipe end-to-end
243
+ run: python -B -m pytest -q -p no:cacheprovider scripts/test_ruflo_recipe.py
@@ -13,7 +13,7 @@ jobs:
13
13
  steps:
14
14
  - uses: actions/checkout@v7
15
15
 
16
- - uses: actions/setup-python@v6
16
+ - uses: actions/setup-python@v7
17
17
  with:
18
18
  python-version: "3.12"
19
19
 
@@ -14,6 +14,53 @@ All notable changes to `loop-engineer` are documented here.
14
14
  `WORKFLOW.md` and `README.md` are reworded to describe the mechanism; the 0.3.4
15
15
  history is left intact.
16
16
 
17
+ ## 0.11.0 — 2026-07-26
18
+
19
+ **Verifier identity, and evidence that is load-bearing.** Two slices of the
20
+ tamper-evident-provenance program ship together, because neither was cut on its own.
21
+
22
+ *Verifier identity and independence (PR #94).* evidence@1 records now carry
23
+ `verified_by.code_digest` and `verified_by.policy_digest` — the runner hashes the
24
+ verifier it actually executed and the goalpost it was held to. `loop doctor`
25
+ reports `self_verified_evidence` when a record declares that its producer also
26
+ verified it, making the independence rule of `reference/safety-and-approvals.md` §5
27
+ a machine check rather than prose. Verify bundles record the visible/held-out
28
+ criterion partition.
29
+
30
+ *Evidence wiring (PR #102).* A verified dispatch binds its evidence digests into
31
+ the hash chain at append time, using the existing `artifact_hashes` envelope field
32
+ — no new event type and still one append per dispatch. The bundle is also written
33
+ to a content-addressed object store whose location is derived from the digest, so
34
+ a third-party reader finds the original bytes from `record["sha256"]` alone and a
35
+ swapped bundle no longer destroys the evidence. `loop doctor` hash-verifies every
36
+ discovered record, re-hashes what the chain bound, and compares a record's
37
+ `policy_digest` against the live `TASKS.json` goalpost. Five new issue codes:
38
+ `evidence_chain_mismatch`, `missing_bound_evidence`, `policy_digest_mismatch`,
39
+ `unverified_evidence_terminal`, `bound_evidence_escape`.
40
+
41
+ **Behavioural flag — `Succeeded` can now mean more.** The opt-in
42
+ `completion_policy.mode: all_required_verified_evidence` requires every cited
43
+ evidence entry to be a workspace-relative record that hash-verifies, **attests a
44
+ pass**, is chain-bound wherever a store exists, and agrees with the live goalpost.
45
+ The default `all_required` is unchanged and every record written before this
46
+ release still validates. The canonical green-marker rule now lives in
47
+ `loop.evidence.verify_bundle_is_green` and is shared object-for-object with
48
+ `scripts/metrics.py`, so a bundle cannot read RED to the FCR gate and GREEN to the
49
+ completion gate.
50
+
51
+ **Known limitations, stated rather than discovered.** Binding makes tampering
52
+ detectable against an anchor, not impossible: without `--expect-chain-head` a
53
+ worker who can rewrite `.loop/` can rewrite the chain too, and a contract with no
54
+ event store cannot chain-bind at all. Deleting `.loop/events.db` after a run leaves
55
+ plain `loop doctor` quiet — the `missing_event_store` tripwire only fires on
56
+ leftover `-wal`/`-shm` residue — so the external anchor is the control that holds.
57
+ Four upgrade notes in `reference/repo-os-contract.md` §17 name the behaviour that
58
+ can turn a previously-clean contract red: `policy_digest_mismatch` is not opt-in
59
+ and has no first-class re-baseline affordance; the `completion_policy` enum
60
+ widening is forward-incompatible as a hard error against an older kernel; `os.link`
61
+ now runs once per dispatch; and a bound artifact above the 64 MiB read cap fails
62
+ doctor with no configuration knob.
63
+
17
64
  ## 0.10.0 — 2026-07-25
18
65
 
19
66
  **The hash-linked event chain.** Every `loop-engineer/event@1` row now carries
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loop-engineer
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: Portable Loop Contract Core: validate and inspect repo-native operating contracts for agent loops.
5
5
  Project-URL: Homepage, https://github.com/SollanSystems/loop-engineer
6
6
  Project-URL: Repository, https://github.com/SollanSystems/loop-engineer
@@ -44,7 +44,7 @@ Description-Content-Type: text/markdown
44
44
  [![CI](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml)
45
45
  [![Python 3.10–3.12](https://img.shields.io/badge/python-3.10%E2%80%933.12-blue)](https://www.python.org/downloads/)
46
46
  [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
47
- [![Release](https://img.shields.io/badge/release-0.10.0-blue)](https://github.com/SollanSystems/loop-engineer/tags)
47
+ [![Release](https://img.shields.io/badge/release-0.11.0-blue)](https://github.com/SollanSystems/loop-engineer/tags)
48
48
 
49
49
  Long-running agents commit **false completion**. After context compaction they
50
50
  forget what "done" meant, optimize to the visible test, patch in circles, and
@@ -67,7 +67,15 @@ ships, on disk and runnable today:
67
67
  hash-chained; `loop doctor --expect-chain-head` verifies the log against an
68
68
  externally anchored head. The chain is tamper-evident **relative to an
69
69
  anchor** — an adversary with workspace write access can rewrite an unanchored
70
- log.
70
+ log. Verify runs record which verifier actually ran — command, code digest
71
+ (recorded only when the verifier is a workspace file, an honest null with a
72
+ named reason otherwise — e.g. `python3 -m pytest`), policy digest — and
73
+ `loop doctor` fails when a record declares that its own
74
+ producer verified it; identity is recorded, not proven: a worker can write a
75
+ false verifier name. A verified dispatch **binds its evidence digests into the
76
+ hash chain**, and `loop doctor` re-hashes them — binding makes tampering
77
+ detectable against an anchor, not impossible: without `--expect-chain-head` a
78
+ worker who can rewrite `.loop/` can rewrite the chain too.
71
79
 
72
80
  ![The inspector scores a self-asserted DIY loop 0/weak, then the gate-backed example 90/strong — both runs live](docs/demo.gif)
73
81
 
@@ -371,7 +379,7 @@ present. Recipe:
371
379
  **CI** — one workflow step validates the contract and publishes a scorecard:
372
380
 
373
381
  ```yaml
374
- - uses: SollanSystems/loop-engineer@v0.10.0
382
+ - uses: SollanSystems/loop-engineer@v0.11.0
375
383
  with:
376
384
  path: "."
377
385
  ```
@@ -464,8 +472,8 @@ doctor` and the contract's own `verify-*` scripts).
464
472
 
465
473
  ## Status
466
474
 
467
- - Version: `0.10.0`
468
- - Release tag: `v0.10.0` (PyPI publish trigger; plugin tags through 0.6.0 used `loop-engineer--v<version>`)
475
+ - Version: `0.11.0`
476
+ - Release tag: `v0.11.0` (PyPI publish trigger; plugin tags through 0.6.0 used `loop-engineer--v<version>`)
469
477
  - License: MIT
470
478
  - Primary interface: Claude Code plugin
471
479
  - Portable core: Python CLI + JSON schemas
@@ -5,7 +5,7 @@
5
5
  [![CI](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml)
6
6
  [![Python 3.10–3.12](https://img.shields.io/badge/python-3.10%E2%80%933.12-blue)](https://www.python.org/downloads/)
7
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
8
- [![Release](https://img.shields.io/badge/release-0.10.0-blue)](https://github.com/SollanSystems/loop-engineer/tags)
8
+ [![Release](https://img.shields.io/badge/release-0.11.0-blue)](https://github.com/SollanSystems/loop-engineer/tags)
9
9
 
10
10
  Long-running agents commit **false completion**. After context compaction they
11
11
  forget what "done" meant, optimize to the visible test, patch in circles, and
@@ -28,7 +28,15 @@ ships, on disk and runnable today:
28
28
  hash-chained; `loop doctor --expect-chain-head` verifies the log against an
29
29
  externally anchored head. The chain is tamper-evident **relative to an
30
30
  anchor** — an adversary with workspace write access can rewrite an unanchored
31
- log.
31
+ log. Verify runs record which verifier actually ran — command, code digest
32
+ (recorded only when the verifier is a workspace file, an honest null with a
33
+ named reason otherwise — e.g. `python3 -m pytest`), policy digest — and
34
+ `loop doctor` fails when a record declares that its own
35
+ producer verified it; identity is recorded, not proven: a worker can write a
36
+ false verifier name. A verified dispatch **binds its evidence digests into the
37
+ hash chain**, and `loop doctor` re-hashes them — binding makes tampering
38
+ detectable against an anchor, not impossible: without `--expect-chain-head` a
39
+ worker who can rewrite `.loop/` can rewrite the chain too.
32
40
 
33
41
  ![The inspector scores a self-asserted DIY loop 0/weak, then the gate-backed example 90/strong — both runs live](docs/demo.gif)
34
42
 
@@ -332,7 +340,7 @@ present. Recipe:
332
340
  **CI** — one workflow step validates the contract and publishes a scorecard:
333
341
 
334
342
  ```yaml
335
- - uses: SollanSystems/loop-engineer@v0.10.0
343
+ - uses: SollanSystems/loop-engineer@v0.11.0
336
344
  with:
337
345
  path: "."
338
346
  ```
@@ -425,8 +433,8 @@ doctor` and the contract's own `verify-*` scripts).
425
433
 
426
434
  ## Status
427
435
 
428
- - Version: `0.10.0`
429
- - Release tag: `v0.10.0` (PyPI publish trigger; plugin tags through 0.6.0 used `loop-engineer--v<version>`)
436
+ - Version: `0.11.0`
437
+ - Release tag: `v0.11.0` (PyPI publish trigger; plugin tags through 0.6.0 used `loop-engineer--v<version>`)
430
438
  - License: MIT
431
439
  - Primary interface: Claude Code plugin
432
440
  - Portable core: Python CLI + JSON schemas
@@ -41,7 +41,7 @@ outputs:
41
41
  runs:
42
42
  using: "composite"
43
43
  steps:
44
- - uses: actions/setup-python@v6
44
+ - uses: actions/setup-python@v7
45
45
  with:
46
46
  python-version: ${{ inputs.python-version }}
47
47
 
@@ -57,7 +57,16 @@ for exactly the machinery our signals miss.
57
57
  Harnesses whose run state lives fundamentally off-repo (OpenHands and
58
58
  SWE-agent trajectories, platform-hosted runs) are out of scope: there is no
59
59
  on-disk run record for a repo-native inspector to read — which is its own
60
- answer to the question this scoreboard asks.
60
+ answer to the question this scoreboard asks.†
61
+
62
+ > † **Correction (2026-07-25).** For OpenHands this is now only half true. The
63
+ > V1 SDK (`openhands-sdk` 1.37.1) persists `base_state.json` + an `events/`
64
+ > trajectory whenever `persistence_dir=` is set — enough for an external
65
+ > certifier to read a run's terminal signal, its iteration cap, and its full
66
+ > event log. It is still not a *repo-native* contract (the record lives outside
67
+ > the repo by default and carries no spec, plan, or ledger), so the row stays
68
+ > out of the scoreboard; but the gap is addressable from outside, which is what
69
+ > [`examples/openhands-certify/`](../../examples/openhands-certify/) does.
61
70
 
62
71
  ## The scoreboard
63
72
 
@@ -283,8 +292,10 @@ FCR/RP — is a missing **layer**, one every harness on this board could emit
283
292
  at its finish line. The port is small: four `loop.emit` calls
284
293
  (`open_contract`, `append_iteration`, `append_receipt`, `terminate`), worked
285
294
  end-to-end for a real engine in
286
- [`docs/integrations/langgraph.md`](../integrations/langgraph.md) and
287
- [`docs/integrations/temporal.md`](../integrations/temporal.md).
295
+ [`docs/integrations/langgraph.md`](../integrations/langgraph.md),
296
+ [`docs/integrations/temporal.md`](../integrations/temporal.md), and — for a
297
+ harness with no seam to hook at all —
298
+ [`docs/integrations/openhands.md`](../integrations/openhands.md).
288
299
 
289
300
  ## Contribute a row
290
301
 
@@ -0,0 +1,118 @@
1
+ # OpenHands — certify the run after it ends
2
+
3
+ OpenHands owns the EXECUTE tier: the autonomous coding runtime that plans, edits,
4
+ runs commands, and decides for itself when it is done. What it cannot do is
5
+ independently check *its own* completion claim — the agent both does the work and
6
+ declares `FINISHED`. Loop Engineer adds the tier *above* it: a contract-and-proof
7
+ layer that turns "the conversation finished" into evidence-backed proof-of-done.
8
+ It never replaces OpenHands; it certifies what OpenHands ran.
9
+
10
+ ## The pattern
11
+
12
+ Unlike LangGraph (`END` edge) or Temporal (certify activity), OpenHands has **no
13
+ seam to insert a certify node into** — the run ends when the agent sets its own
14
+ execution status. So the recipe is a **post-run certifier** over the record the SDK
15
+ already persisted:
16
+
17
+ ```
18
+ <persistence_dir>/<conversation-id-hex>/base_state.json # execution_status, max_iterations, stats
19
+ <persistence_dir>/<conversation-id-hex>/events/event-00000-<uuid>.json ← the trajectory
20
+ events/event-00001-<uuid>.json
21
+ ```
22
+
23
+ The conversation id segment is the UUID **hex** (32 chars, no hyphens); a
24
+ conversation only persists when you pass `persistence_dir=`. The certifier takes a
25
+ conversation dir directly, so that composition rule is documentation, not code.
26
+
27
+ ```python
28
+ from loop import emit
29
+ from loop.integrations import EngineOutcome, to_terminal_state
30
+
31
+ state = json.loads((conv_dir / "base_state.json").read_text(encoding="utf-8"))
32
+ events = sorted((conv_dir / "events").glob("event-*.json"), key=event_index)
33
+
34
+ gate = holdout_gate.decide(visible, withheld) # visible green + withheld green?
35
+ ac = anticheat_scan.scan(diff_text=git_diff, trajectory=[str(p) for p in events])
36
+ terminal = to_terminal_state(
37
+ outcome=to_engine_outcome(state, events, artifacts=[...]),
38
+ gate_verdict=gate, anticheat=ac,
39
+ criteria_met={"1": gate["verdict"] == "Succeeded"},
40
+ )
41
+ emit.terminate(ws, state=terminal["state"], criteria_met=terminal["criteria_met"],
42
+ evidence=terminal["evidence"], false_completion=terminal["false_completion"],
43
+ reason=terminal["reason"], iteration_id=1)
44
+ ```
45
+
46
+ The certifier **imports no `openhands` package** — the record is plain JSON, so it
47
+ runs on Python 3.10 even though the SDK requires 3.12, and the gate needs no LLM
48
+ key. The event log doubles as the trajectory fed to `anticheat_scan.scan`: the
49
+ "the runtime ran the tests but the agent read the answer key" case OpenHands
50
+ cannot catch about itself, because the answer key is not part of its contract.
51
+
52
+ ## OpenHands signal → typed terminal state
53
+
54
+ | `base_state.json` signal | `EngineOutcome` field | Typed terminal state |
55
+ |---|---|---|
56
+ | `execution_status: "finished"`, gate green + anticheat clean | `reached_end=True` | `Succeeded` |
57
+ | `execution_status: "finished"`, visible green / withheld red | `reached_end=True` | `FailedUnverifiable` (`false_completion: true`) |
58
+ | `execution_status: "stuck"` (stuck detector) | `budget_exhausted=True` | `FailedBudget` |
59
+ | `execution_status: "error"` + `ConversationErrorEvent.code == "MaxIterationsReached"` | `budget_exhausted=True` | `FailedBudget` |
60
+ | `execution_status: "error"`, any other code | `external_error="<code>: <detail>"` | `FailedBlocked` |
61
+ | `execution_status: "paused"` (`conversation.pause()`) | `human_abort=True` | `AbortedByHuman` |
62
+ | `idle` / `running` / `waiting_for_confirmation` (read mid-flight or abandoned) | `reached_end=False` | `FailedUnverifiable` |
63
+ | trajectory touched an answer-key path (anticheat HIGH) | — | `FailedUnverifiable` |
64
+ | the diff edits a gate script (anticheat CRITICAL) | — | `FailedSafety` |
65
+
66
+ **The precedence trap.** A max-iteration stop arrives *as*
67
+ `execution_status == "error"` with a `ConversationErrorEvent` whose `code` is
68
+ `MaxIterationsReached`. Since `to_terminal_state` ranks blocked above budget,
69
+ setting **both** `external_error` and `budget_exhausted` reports `FailedBlocked`
70
+ and silently loses the budget signal. Inspect the error code first and set
71
+ **exactly one**. `code` is a free-form `str`, so anything unrecognized falls
72
+ through to `FailedBlocked` — which fails safe: an unclassified error can never
73
+ become `Succeeded`.
74
+
75
+ ## Zero-install mode
76
+
77
+ The `loop.integrations` module is convenience, not a requirement — the whole
78
+ projection is the SAME ~15 lines the LangGraph and Temporal recipes paste
79
+ (the adapter is engine-neutral):
80
+
81
+ ```python
82
+ def to_terminal(gate, anticheat, criteria_met, evidence,
83
+ *, human_abort=False, blocked=None, over_budget=False):
84
+ fc = gate.get("false_completion") is True
85
+ if anticheat.get("downgrade_to") == "FailedSafety": state = "FailedSafety"
86
+ elif human_abort: state = "AbortedByHuman"
87
+ elif blocked: state = "FailedBlocked"
88
+ elif over_budget: state = "FailedBudget"
89
+ elif any(v is None for v in criteria_met.values()): state = "FailedSpecGap"
90
+ elif (not gate or not anticheat or anticheat.get("downgrade_to")
91
+ or gate.get("verdict") != "Succeeded" or fc
92
+ or not any(criteria_met.values()) or not evidence): state = "FailedUnverifiable"
93
+ else: state = "Succeeded"
94
+ return {"schema": "loop-engineer/terminal@1", "state": state,
95
+ "criteria_met": {k: v is True for k, v in criteria_met.items()},
96
+ "evidence": list(evidence), "false_completion": fc}
97
+ ```
98
+
99
+ ## Gate it in CI
100
+
101
+ ```yaml
102
+ - run: pip install loop-engineer
103
+ - run: python certify_run.py run/ --conversation "$CONV_DIR" --agent-workspace "$WS"
104
+ - run: loop doctor run/ # -> {"ok": true}: the contract is structurally honest
105
+ - run: loop metrics run/ # -> false_completion_rate + evidence-backed scorecard
106
+ ```
107
+
108
+ `loop metrics` scores the run from its on-disk evidence — not the agent's narration.
109
+
110
+ Verified against `openhands-sdk` 1.37.1 (2026-07-25), MIT
111
+ ([`OpenHands/software-agent-sdk`](https://github.com/OpenHands/software-agent-sdk),
112
+ "Copyright (c) 2026 OpenHands contributors" — PyPI carries no license metadata).
113
+ The persistence layout, the `ConversationExecutionStatus` members, and the
114
+ `MaxIterationsReached` literal are pinned live by
115
+ [`scripts/test_openhands_sdk_drift.py`](../../scripts/test_openhands_sdk_drift.py).
116
+
117
+ Full runnable example (six committed fixture conversations + the false-completion
118
+ demo): [`examples/openhands-certify/`](../../examples/openhands-certify/).