loop-engineer 0.9.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 (383) hide show
  1. {loop_engineer-0.9.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.9.0 → loop_engineer-0.11.0}/.github/workflows/publish.yml +1 -1
  4. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/CHANGELOG.md +132 -1
  5. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/PKG-INFO +18 -6
  6. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/README.md +17 -5
  7. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/action.yml +43 -2
  8. {loop_engineer-0.9.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.9.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.9.0 → loop_engineer-0.11.0}/loop/__main__.py +69 -6
  51. loop_engineer-0.11.0/loop/chain.py +88 -0
  52. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/completion.py +22 -3
  53. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/contract.py +348 -5
  54. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/emit.py +204 -2
  55. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/events.py +103 -10
  56. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/evidence.py +148 -10
  57. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/integrations.py +8 -0
  58. loop_engineer-0.11.0/loop/migrate.py +45 -0
  59. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/paths.py +7 -0
  60. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/reducer.py +44 -3
  61. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/runcontrol.py +9 -1
  62. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/runner.py +143 -35
  63. loop_engineer-0.11.0/loop/runtime.py +414 -0
  64. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/simulate.py +4 -7
  65. loop_engineer-0.11.0/loop/verifier.py +148 -0
  66. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/pyproject.toml +1 -1
  67. loop_engineer-0.11.0/reference/repo-os-contract.md +1509 -0
  68. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/safety-and-approvals.md +4 -0
  69. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/event.schema.json +4 -2
  70. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/evidence.schema.json +16 -3
  71. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/tasks.schema.json +5 -1
  72. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/terminal.schema.json +4 -1
  73. loop_engineer-0.11.0/scripts/chain_fixtures.py +66 -0
  74. loop_engineer-0.11.0/scripts/ci_anchor_probe.py +83 -0
  75. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/metrics.py +29 -3
  76. loop_engineer-0.11.0/scripts/test_adversarial_chain.py +345 -0
  77. loop_engineer-0.11.0/scripts/test_adversarial_evidence_binding.py +540 -0
  78. loop_engineer-0.11.0/scripts/test_adversarial_verifier_identity.py +268 -0
  79. loop_engineer-0.11.0/scripts/test_bound_artifact_view.py +233 -0
  80. loop_engineer-0.11.0/scripts/test_ci_anchor_probe.py +53 -0
  81. loop_engineer-0.11.0/scripts/test_completion_verdict.py +258 -0
  82. loop_engineer-0.11.0/scripts/test_completion_verified_evidence.py +366 -0
  83. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_conformance.py +141 -0
  84. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_version.py +12 -2
  85. loop_engineer-0.11.0/scripts/test_doctor_eventstore.py +524 -0
  86. loop_engineer-0.11.0/scripts/test_doctor_evidence.py +147 -0
  87. loop_engineer-0.11.0/scripts/test_doctor_evidence_binding.py +189 -0
  88. loop_engineer-0.11.0/scripts/test_doctor_evidence_verification.py +211 -0
  89. loop_engineer-0.11.0/scripts/test_doctor_store_read_guard.py +55 -0
  90. loop_engineer-0.11.0/scripts/test_event_chain.py +610 -0
  91. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_evidence.py +103 -1
  92. loop_engineer-0.11.0/scripts/test_evidence_binding_runner.py +139 -0
  93. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_cli.py +1 -1
  94. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_cli_status_replay.py +10 -3
  95. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_cli.py +1 -1
  96. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_zero_writes.py +28 -3
  97. loop_engineer-0.11.0/scripts/test_metrics_verifier_source.py +100 -0
  98. loop_engineer-0.11.0/scripts/test_migrate_cli.py +128 -0
  99. loop_engineer-0.11.0/scripts/test_openhands_recipe.py +205 -0
  100. loop_engineer-0.11.0/scripts/test_openhands_sdk_drift.py +75 -0
  101. loop_engineer-0.11.0/scripts/test_ruflo_recipe.py +199 -0
  102. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_runner_dispatch.py +111 -1
  103. loop_engineer-0.11.0/scripts/test_verifier_identity.py +180 -0
  104. loop_engineer-0.11.0/scripts/test_verify_evidence_object_collision.py +67 -0
  105. loop_engineer-0.11.0/scripts/test_verify_evidence_objects.py +150 -0
  106. loop_engineer-0.11.0/scripts/test_verify_evidence_writer.py +185 -0
  107. loop_engineer-0.9.0/.github/workflows/ci.yml +0 -113
  108. loop_engineer-0.9.0/loop/runtime.py +0 -223
  109. loop_engineer-0.9.0/reference/repo-os-contract.md +0 -780
  110. loop_engineer-0.9.0/scripts/test_doctor_eventstore.py +0 -166
  111. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.claude-plugin/marketplace.json +0 -0
  112. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  113. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  114. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  115. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  116. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/dependabot.yml +0 -0
  117. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.gitignore +0 -0
  118. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.pre-commit-hooks.yaml +0 -0
  119. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/CODE_OF_CONDUCT.md +0 -0
  120. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/CONTRIBUTING.md +0 -0
  121. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/GLOSSARY.md +0 -0
  122. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/LICENSE +0 -0
  123. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/SECURITY.md +0 -0
  124. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/ROADMAP-v1.0.md +0 -0
  125. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/adr/0001-proof-kernel-and-runtime.md +0 -0
  126. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/01-good-first-qw9-trigger-phrases.md +0 -0
  127. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/02-good-first-qw10-self-eval-labels.md +0 -0
  128. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/03-good-first-emit-metrics-vocabulary.md +0 -0
  129. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/04-help-wanted-openhands-recipe.md +0 -0
  130. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/05-help-wanted-ruflo-recipe.md +0 -0
  131. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/06-help-wanted-gap-reports.md +0 -0
  132. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/07-help-wanted-emit-scaffold-runlog-seed.md +0 -0
  133. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/demo.cast +0 -0
  134. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/demo.gif +0 -0
  135. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/gap-reports/superpowers.md +0 -0
  136. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/integrations/langgraph.md +0 -0
  137. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/integrations/temporal.md +0 -0
  138. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/metrics-baseline.json +0 -0
  139. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/social-card.png +0 -0
  140. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-20-loop-engineer-v1.md +0 -0
  141. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-30-loop-engineer-v1.0-roadmap.md +0 -0
  142. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-03-adoption-slices.md +0 -0
  143. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-08-v0.8.0-composes-the-field.md +0 -0
  144. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-09-st5-harness-scoreboard.md +0 -0
  145. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-20-loop-engineer-design.md +0 -0
  146. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st1-metrics-baseline.md +0 -0
  147. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st2-portable-contract-spec.md +0 -0
  148. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-v04-credibility-enforcement.md +0 -0
  149. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-03-adoption-slices-design.md +0 -0
  150. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-08-v0.8.0-composes-the-field-design.md +0 -0
  151. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-09-st5-harness-scoreboard-design.md +0 -0
  152. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/evals/cases/structural.json +0 -0
  153. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/evals/rubric.md +0 -0
  154. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/README.md +0 -0
  155. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/mission.md +0 -0
  156. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/roadmap.md +0 -0
  157. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/plan.md +0 -0
  158. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/references.md +0 -0
  159. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/shape.md +0 -0
  160. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/specs/2026-07-09-1030-csv-dedupe/standards.md +0 -0
  161. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/backend/data-imports.md +0 -0
  162. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/index.yml +0 -0
  163. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/README.md +0 -0
  164. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad/bmm/config.yaml +0 -0
  165. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/1-1-deduplicate-csv-rows.md +0 -0
  166. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/epic-1-retro-2026-07-09.md +0 -0
  167. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/sprint-status.yaml +0 -0
  168. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/epics.md +0 -0
  169. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/prd.md +0 -0
  170. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/src/import_contacts.py +0 -0
  171. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/tests/test_import_contacts.py +0 -0
  172. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235-analysis.md +0 -0
  173. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235.md +0 -0
  174. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/epic.md +0 -0
  175. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/execution-status.md +0 -0
  176. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/github-mapping.md +0 -0
  177. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/progress.md +0 -0
  178. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/stream-A.md +0 -0
  179. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/prds/csv-dedupe.md +0 -0
  180. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/README.md +0 -0
  181. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/approvals/.gitkeep +0 -0
  182. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-run.txt +0 -0
  183. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-verdict.json +0 -0
  184. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T1.json +0 -0
  185. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2-iter1.json +0 -0
  186. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2.json +0 -0
  187. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/checkpoints/.gitkeep +0 -0
  188. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/manifest.yaml +0 -0
  189. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/memory/.gitkeep +0 -0
  190. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/repair/iter-002.json +0 -0
  191. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/state.json +0 -0
  192. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/ADR.md +0 -0
  193. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/README.md +0 -0
  194. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/RUNLOG.md +0 -0
  195. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/SPEC.md +0 -0
  196. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/TASKS.json +0 -0
  197. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/WORKFLOW.md +0 -0
  198. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/run-example +0 -0
  199. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-fast +0 -0
  200. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-full +0 -0
  201. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/manifest.json +0 -0
  202. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/measure_coverage.py +0 -0
  203. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/pricing.py +0 -0
  204. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_holdout.py +0 -0
  205. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_visible.py +0 -0
  206. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/terminal_state.json +0 -0
  207. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/absolute-uri.json +0 -0
  208. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/bad-sha256-pattern.json +0 -0
  209. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/missing-required-field.json +0 -0
  210. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/scheme-uri.json +0 -0
  211. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/valid-evidence.json +0 -0
  212. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/holdout-verdict.json +0 -0
  213. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1-iter1.json +0 -0
  214. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1.json +0 -0
  215. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/manifest.yaml +0 -0
  216. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/repair/iter-002.json +0 -0
  217. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/state.json +0 -0
  218. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/terminal_state.json +0 -0
  219. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/README.md +0 -0
  220. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/RUNLOG.md +0 -0
  221. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/SPEC.md +0 -0
  222. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/TASKS.json +0 -0
  223. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/WORKFLOW.md +0 -0
  224. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/run-example +0 -0
  225. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-fast +0 -0
  226. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-full +0 -0
  227. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/jobs.py +0 -0
  228. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/manifest.json +0 -0
  229. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/measure_stability.py +0 -0
  230. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_holdout.py +0 -0
  231. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_visible.py +0 -0
  232. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/langgraph-emit/README.md +0 -0
  233. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/langgraph-emit/graph_example.py +0 -0
  234. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/naive-loop/.loop/state.json +0 -0
  235. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/naive-loop/README.md +0 -0
  236. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/README.md +0 -0
  237. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/.openspec.yaml +0 -0
  238. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/design.md +0 -0
  239. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/proposal.md +0 -0
  240. {loop_engineer-0.9.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
  241. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/changes/archive/2026-07-09-dedupe-csv-rows/tasks.md +0 -0
  242. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/config.yaml +0 -0
  243. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/specs/csv-dedupe/spec.md +0 -0
  244. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/plans/coverage-repair.plan.json +0 -0
  245. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/plans/invalid/cyclic-dependency.plan.json +0 -0
  246. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/plans/invalid/missing-goal.plan.json +0 -0
  247. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/plans/completed/csv-dedupe.plan.md +0 -0
  248. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/prds/csv-dedupe.prd.md +0 -0
  249. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reports/csv-dedupe-report.md +0 -0
  250. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-cycle-0.verdict.json +0 -0
  251. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-review.md +0 -0
  252. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.run.log +0 -0
  253. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.state.json +0 -0
  254. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/README.md +0 -0
  255. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/swarm-activity.json +0 -0
  256. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/v3-progress.json +0 -0
  257. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/security/audit-status.json +0 -0
  258. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.hive-mind/sessions/hive-mind-prompt-swarm-2026-07-09.txt +0 -0
  259. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.mcp.json +0 -0
  260. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.swarm/memory-export.json +0 -0
  261. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/README.md +0 -0
  262. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/feature.json +0 -0
  263. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/memory/constitution.md +0 -0
  264. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/README.md +0 -0
  265. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/checklists/requirements.md +0 -0
  266. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/plan.md +0 -0
  267. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/quickstart.md +0 -0
  268. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/research.md +0 -0
  269. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/spec.md +0 -0
  270. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/tasks.md +0 -0
  271. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/.superpowers/sdd/progress.md +0 -0
  272. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/README.md +0 -0
  273. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/docs/superpowers/plans/2026-07-08-csv-dedupe.md +0 -0
  274. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/docs/superpowers/specs/2026-07-08-csv-dedupe-design.md +0 -0
  275. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/config.json +0 -0
  276. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/docs/prd.txt +0 -0
  277. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/reports/task-complexity-report.json +0 -0
  278. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/state.json +0 -0
  279. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/task_001.txt +0 -0
  280. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/tasks.json +0 -0
  281. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/templates/example_prd.txt +0 -0
  282. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/CLAUDE.md +0 -0
  283. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/README.md +0 -0
  284. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/temporal-certify/README.md +0 -0
  285. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/temporal-certify/workflow_example.py +0 -0
  286. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/hooks/stop_firewall.py +0 -0
  287. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/__init__.py +0 -0
  288. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/_resources.py +0 -0
  289. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/architect.py +0 -0
  290. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/foreign.py +0 -0
  291. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/fsm.py +0 -0
  292. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/plan.py +0 -0
  293. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/scaffold.py +0 -0
  294. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/architecture-matrix.md +0 -0
  295. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/eval-suite.md +0 -0
  296. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/loop-patterns.md +0 -0
  297. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/model-routing.md +0 -0
  298. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/platform-map.md +0 -0
  299. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/prompt-templates.md +0 -0
  300. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/manifest.schema.json +0 -0
  301. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/plan.schema.json +0 -0
  302. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/receipt.schema.json +0 -0
  303. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/repair-record.schema.json +0 -0
  304. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/rollout-record.schema.json +0 -0
  305. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/state.schema.json +0 -0
  306. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/action_scorecard.py +0 -0
  307. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/anticheat_scan.py +0 -0
  308. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/benchmark_harness.py +0 -0
  309. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/holdout_gate.py +0 -0
  310. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/inspect_loop.py +0 -0
  311. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/rollout_ledger.py +0 -0
  312. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/runtime_monitor.py +0 -0
  313. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/self_eval.py +0 -0
  314. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_action_scorecard.py +0 -0
  315. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_adversarial_kernel.py +0 -0
  316. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_adversarial_process.py +0 -0
  317. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_anticheat_scan.py +0 -0
  318. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_benchmark_harness.py +0 -0
  319. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_ci_release_mode.py +0 -0
  320. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_completion_policy.py +0 -0
  321. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_contract_records.py +0 -0
  322. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_adoption.py +0 -0
  323. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_baseline.py +0 -0
  324. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_claims.py +0 -0
  325. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_emit.py +0 -0
  326. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_eventstore.py +0 -0
  327. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_example_runnable.py +0 -0
  328. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_flaky_example.py +0 -0
  329. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_foreign_inspect.py +0 -0
  330. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_fsm.py +0 -0
  331. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_holdout_gate.py +0 -0
  332. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_inspect_loop.py +0 -0
  333. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_integrations.py +0 -0
  334. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe.py +0 -0
  335. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe_st3.py +0 -0
  336. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_architect_cli.py +0 -0
  337. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_contract_core.py +0 -0
  338. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_runcontrol_cli.py +0 -0
  339. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_manifest_extra_states_schema.py +0 -0
  340. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_metrics.py +0 -0
  341. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_metrics_cli.py +0 -0
  342. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_plan_schema.py +0 -0
  343. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_precommit_hook.py +0 -0
  344. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_reducer.py +0 -0
  345. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_resources.py +0 -0
  346. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_rollout_ledger.py +0 -0
  347. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_runner_verifier.py +0 -0
  348. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_runtime_monitor.py +0 -0
  349. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_scaffold.py +0 -0
  350. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_schemas_metrics.py +0 -0
  351. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_self_eval.py +0 -0
  352. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_state_vocabulary.py +0 -0
  353. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_stop_firewall.py +0 -0
  354. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_template_roundtrip.py +0 -0
  355. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_temporal_recipe.py +0 -0
  356. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_validate_frontmatter.py +0 -0
  357. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_wheel_selfcontained.py +0 -0
  358. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/validate_frontmatter.py +0 -0
  359. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-architect/SKILL.md +0 -0
  360. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-contract/SKILL.md +0 -0
  361. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-engineer/SKILL.md +0 -0
  362. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-evals/SKILL.md +0 -0
  363. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-flywheel/SKILL.md +0 -0
  364. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-inspector/SKILL.md +0 -0
  365. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-inspector/reference/patterns.md +0 -0
  366. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-repair/SKILL.md +0 -0
  367. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-run/SKILL.md +0 -0
  368. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/SKILL.md +0 -0
  369. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/reference/patterns.md +0 -0
  370. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/AGENTS.md.tmpl +0 -0
  371. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/EVALS-rubric.md.tmpl +0 -0
  372. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/RUNLOG.md.tmpl +0 -0
  373. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/SPEC.md.tmpl +0 -0
  374. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/TASKS.json.tmpl +0 -0
  375. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/WORKFLOW.md.tmpl +0 -0
  376. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/extract-trace-metrics.sh +0 -0
  377. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/judge-rubric.sh +0 -0
  378. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/manifest.yaml.tmpl +0 -0
  379. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/state.json.tmpl +0 -0
  380. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/terminal_state.json.tmpl +0 -0
  381. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/verify-fast.sh +0 -0
  382. {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/verify-full.sh +0 -0
  383. {loop_engineer-0.9.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.9.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,137 @@ 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
+
64
+ ## 0.10.0 — 2026-07-25
65
+
66
+ **The hash-linked event chain.** Every `loop-engineer/event@1` row now carries
67
+ `prev_event_hash` and `event_hash` — a sha256 over a canonical JSON preimage of
68
+ the event's hashed fields, `prev_event_hash` among them. Canonical form is
69
+ `json.dumps(sort_keys=True, separators=(",", ":"), ensure_ascii=False,
70
+ allow_nan=False)` encoded UTF-8, pinned normatively with conformance vectors in
71
+ `reference/repo-os-contract.md` §16. The digest is computed **inside the store on
72
+ append**, never supplied by a caller, and the deterministic reducer re-verifies
73
+ each link as it folds: a spliced, reordered, or edited row raises
74
+ `ChainBreakError` and stops the fold instead of projecting a plausible state.
75
+ `loop.chain` is stdlib-only and imports no other module of this package, so
76
+ `verify_chain()` re-verifies an exported event stream without the store code
77
+ (#82).
78
+
79
+ **Store generations and `loop migrate`.** A fresh store stamps `PRAGMA
80
+ user_version = 2` and widens the `events` DDL with `event_hash TEXT NOT NULL`.
81
+ `loop migrate` is the only store-upgrade path — explicit, idempotent, and
82
+ non-rewriting: it adds the two columns and stamps `user_version = 2`, but never
83
+ backfills hashes onto existing rows, because the append-only `BEFORE UPDATE`
84
+ trigger forbids it. Pre-migration rows therefore stay an **unchained prefix**
85
+ that doctor reports rather than elides, and the first post-migration append is a
86
+ chain genesis.
87
+
88
+ **Anchored doctor gate.** `loop doctor` gains an `event_store.chain` block
89
+ (`head`, `unchained_prefix`) and a `--expect-chain-head SHA256` flag — also
90
+ accepted by `validate` and `verify` — that fails the gate unless the store's head
91
+ equals an externally remembered anchor. Four new issue codes: `event_chain_broken`
92
+ (a link does not verify), `chain_anchor_mismatch` (the head differs from the
93
+ supplied anchor, or an anchor was supplied with no readable store),
94
+ `missing_event_store` (`events.db` is absent while SQLite sidecars remain — the
95
+ store was deleted), and `chain_columns_missing` (the store still declares
96
+ generation 2 with its chain columns gone — the lazy downgrade). The composite
97
+ action publishes the observed head as a `chain-head` output on every run and
98
+ optionally enforces one through an `expect-chain-head` input.
99
+
100
+ **Integrity boundary.** The chain is **tamper-evident relative to an anchored
101
+ head** — a detection property, not a prevention one, and scoped to the anchor.
102
+ It detects splicing, reordering, an edit that does not recompute every downstream
103
+ digest, and byte corruption of any hashed field; given an anchor it detects *any*
104
+ divergence from the head that anchor names, including tail truncation, which is
105
+ otherwise invisible because deleting trailing events leaves a shorter but
106
+ internally valid chain. It does **not** detect a full in-workspace recompute, a
107
+ chain-column downgrade that also resets `user_version`, deletion of the store when
108
+ no sidecars remain and no anchor is supplied, well-formed lies (nothing in the
109
+ chain judges whether a payload is true), or anything in a never-migrated prefix.
110
+ And the window stays open at the head: "An anchor certifies the log only up to the
111
+ anchored head. Everything appended after the last externally-read anchor —
112
+ including a rewrite of the suffix — is unverified until the next anchor is read
113
+ and remembered outside the workspace. The chain narrows the tampering window; it
114
+ does not close it." `scripts/test_adversarial_chain.py` pins both sides — the
115
+ attacks that are caught and four `PINNED LIMITATION` cases that are not. The full
116
+ boundary, with the anchor's trust assumptions, is normative in
117
+ `reference/repo-os-contract.md` §16.
118
+
119
+ **Stricter reads.** `status`, `replay`, and `doctor` now **reject** a store
120
+ containing any schema-invalid event, raising `invalid_event` instead of silently
121
+ folding past it as they did in 0.9.0. Validation runs before the fold, so a tamper
122
+ that also violates `event@1` surfaces as `invalid_event` rather than
123
+ `event_chain_broken`.
124
+
125
+ **Sidecars resolved.** Read verbs no longer leave `-wal`/`-shm` files beside a
126
+ clean `.loop/events.db` — the 0.9.0 known limitation recorded below. #80 landed
127
+ the first half, opening read-only connections with `immutable=1` when no WAL
128
+ sidecar exists; this release completes it with a two-stage retry so that a lost
129
+ `immutable=1` race against a live writer retries plainly as `mode=ro` before
130
+ anything may be called corruption, the same read path in the runner, and a
131
+ zero-carve-out tripwire proving every read verb leaves a clean store
132
+ byte-identical on both store generations.
133
+
134
+ **Compatibility, both directions.** Pre-0.10.0 *readers* can read a v2 store:
135
+ their explicit ten-column `SELECT` is unaffected by the two added columns.
136
+ Pre-0.10.0 *writers* must not append to a chained store. A fresh v0.10.0 store
137
+ refuses such an append at the database, because `event_hash` is `NOT NULL`; a
138
+ *migrated* store keeps its columns nullable, so the append succeeds and produces a
139
+ permanent, unrepairable `event_chain_broken` — the row cannot be re-linked
140
+ afterwards, since `UPDATE` is trigger-blocked. Pin your `loop-engineer` and action
141
+ version per store.
142
+
143
+ Test baseline: 1021 passed / 16 skipped with the `yaml`+`schemas` extras;
144
+ 951 / 86 in structural-fallback mode (PyYAML only). Both measured in a fresh
145
+ worktree; a live checkout reads +2 passed / −2 skipped through two
146
+ checked-when-present tests.
147
+
17
148
  ## 0.9.0 — 2026-07-17
18
149
 
19
150
  **The event-sourced kernel.** The contract gains a durable runtime substrate:
@@ -71,7 +202,7 @@ least-privilege workflow permissions (#46, #47).
71
202
  `-wal`/`-shm` sidecars next to `.loop/events.db` (read-only connections
72
203
  recreate them and cannot checkpoint on close). Store content is never
73
204
  mutated, but tree-byte-identity checks over a store-backed workspace will
74
- notice them.
205
+ notice them. *(Resolved in 0.10.0 — see "Sidecars resolved" above.)*
75
206
 
76
207
  Test baseline: 933 passed / 16 skipped with the `yaml`+`schemas` extras;
77
208
  864 / 85 in structural-fallback mode (PyYAML only).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loop-engineer
3
- Version: 0.9.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.9.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
@@ -63,7 +63,19 @@ ships, on disk and runnable today:
63
63
  - an **event-sourced runtime** — `run`, `status`, `replay`, `simulate`, and
64
64
  approve/pause/resume/cancel over an append-only SQLite event log
65
65
  (`.loop/events.db`), folded by a deterministic reducer that enforces the same
66
- completion gate as the writers, with crash-safe single-step resume.
66
+ completion gate as the writers, with crash-safe single-step resume. Events are
67
+ hash-chained; `loop doctor --expect-chain-head` verifies the log against an
68
+ externally anchored head. The chain is tamper-evident **relative to an
69
+ anchor** — an adversary with workspace write access can rewrite an unanchored
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.
67
79
 
68
80
  ![The inspector scores a self-asserted DIY loop 0/weak, then the gate-backed example 90/strong — both runs live](docs/demo.gif)
69
81
 
@@ -367,7 +379,7 @@ present. Recipe:
367
379
  **CI** — one workflow step validates the contract and publishes a scorecard:
368
380
 
369
381
  ```yaml
370
- - uses: SollanSystems/loop-engineer@v0.9.0
382
+ - uses: SollanSystems/loop-engineer@v0.11.0
371
383
  with:
372
384
  path: "."
373
385
  ```
@@ -460,8 +472,8 @@ doctor` and the contract's own `verify-*` scripts).
460
472
 
461
473
  ## Status
462
474
 
463
- - Version: `0.9.0`
464
- - Release tag: `v0.9.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>`)
465
477
  - License: MIT
466
478
  - Primary interface: Claude Code plugin
467
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.9.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
@@ -24,7 +24,19 @@ ships, on disk and runnable today:
24
24
  - an **event-sourced runtime** — `run`, `status`, `replay`, `simulate`, and
25
25
  approve/pause/resume/cancel over an append-only SQLite event log
26
26
  (`.loop/events.db`), folded by a deterministic reducer that enforces the same
27
- completion gate as the writers, with crash-safe single-step resume.
27
+ completion gate as the writers, with crash-safe single-step resume. Events are
28
+ hash-chained; `loop doctor --expect-chain-head` verifies the log against an
29
+ externally anchored head. The chain is tamper-evident **relative to an
30
+ anchor** — an adversary with workspace write access can rewrite an unanchored
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.
28
40
 
29
41
  ![The inspector scores a self-asserted DIY loop 0/weak, then the gate-backed example 90/strong — both runs live](docs/demo.gif)
30
42
 
@@ -328,7 +340,7 @@ present. Recipe:
328
340
  **CI** — one workflow step validates the contract and publishes a scorecard:
329
341
 
330
342
  ```yaml
331
- - uses: SollanSystems/loop-engineer@v0.9.0
343
+ - uses: SollanSystems/loop-engineer@v0.11.0
332
344
  with:
333
345
  path: "."
334
346
  ```
@@ -421,8 +433,8 @@ doctor` and the contract's own `verify-*` scripts).
421
433
 
422
434
  ## Status
423
435
 
424
- - Version: `0.9.0`
425
- - Release tag: `v0.9.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>`)
426
438
  - License: MIT
427
439
  - Primary interface: Claude Code plugin
428
440
  - Portable core: Python CLI + JSON schemas
@@ -25,11 +25,23 @@ inputs:
25
25
  description: "Token for the optional PR scorecard comment. Empty skips the comment."
26
26
  required: false
27
27
  default: ""
28
+ expect-chain-head:
29
+ description: >-
30
+ Fail the gate unless the store's chain head equals this 64-hex value (an
31
+ externally remembered anchor). Empty performs NO cross-run tamper
32
+ detection — the gate then only records the head for a later comparison.
33
+ required: false
34
+ default: ""
35
+
36
+ outputs:
37
+ chain-head:
38
+ description: "Chain head event_hash observed by this gate run ('' when the store has no chained events)."
39
+ value: ${{ steps.chain-head.outputs.chain-head }}
28
40
 
29
41
  runs:
30
42
  using: "composite"
31
43
  steps:
32
- - uses: actions/setup-python@v6
44
+ - uses: actions/setup-python@v7
33
45
  with:
34
46
  python-version: ${{ inputs.python-version }}
35
47
 
@@ -50,12 +62,17 @@ runs:
50
62
  shell: bash
51
63
  env:
52
64
  LOOP_PATH: "${{ inputs.path }}"
65
+ LOOP_EXPECT_HEAD: "${{ inputs.expect-chain-head }}"
53
66
  run: |
54
67
  # -eo pipefail (GitHub's bash default) makes a doctor failure fail the step
55
68
  # despite the tee. Then assert the strict validation path actually ran, so a
56
69
  # future packaging regression that drops the extras fails loudly here. The
57
70
  # check reads one fixed field from doctor's own JSON — no fragile parsing.
58
- loop doctor "$LOOP_PATH" | tee "${RUNNER_TEMP}/doctor.json"
71
+ if [ -n "$LOOP_EXPECT_HEAD" ]; then
72
+ loop doctor --expect-chain-head "$LOOP_EXPECT_HEAD" "$LOOP_PATH" | tee "${RUNNER_TEMP}/doctor.json"
73
+ else
74
+ loop doctor "$LOOP_PATH" | tee "${RUNNER_TEMP}/doctor.json"
75
+ fi
59
76
  python - "${RUNNER_TEMP}/doctor.json" <<'PY'
60
77
  import json, sys
61
78
  mode = json.load(open(sys.argv[1])).get("validation_mode")
@@ -65,6 +82,30 @@ runs:
65
82
  raise SystemExit(1)
66
83
  PY
67
84
 
85
+ - name: chain head (anchor surface)
86
+ id: chain-head
87
+ if: always()
88
+ shell: bash
89
+ run: |
90
+ # Runs even when doctor failed: an anchor MISMATCH is exactly the run whose
91
+ # observed head an operator needs recorded. Absent/empty doctor.json (doctor
92
+ # never got to write one) is a silent no-op, not an error.
93
+ [ -s "${RUNNER_TEMP}/doctor.json" ] || exit 0
94
+ python - "${RUNNER_TEMP}/doctor.json" "$GITHUB_STEP_SUMMARY" "$GITHUB_OUTPUT" <<'PY'
95
+ import json, sys
96
+ try:
97
+ doctor = json.load(open(sys.argv[1]))
98
+ except (OSError, json.JSONDecodeError):
99
+ doctor = {}
100
+ chain = (doctor.get("event_store") or {}).get("chain") or {}
101
+ head = chain.get("head") or {}
102
+ value = head.get("event_hash") or ""
103
+ line = (f"**loop-engineer chain head:** `{value}` (sequence {head.get('sequence')})"
104
+ if value else "**loop-engineer chain head:** none (no chained events)")
105
+ open(sys.argv[2], "a").write(line + "\n")
106
+ open(sys.argv[3], "a").write(f"chain-head={value}\n")
107
+ PY
108
+
68
109
  - name: loop inspect (scorecard)
69
110
  shell: bash
70
111
  env:
@@ -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