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.
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.claude-plugin/plugin.json +1 -1
- loop_engineer-0.11.0/.github/workflows/ci.yml +243 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/workflows/publish.yml +1 -1
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/CHANGELOG.md +47 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/PKG-INFO +14 -6
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/README.md +13 -5
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/action.yml +1 -1
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/gap-reports/scoreboard.md +14 -3
- loop_engineer-0.11.0/docs/integrations/openhands.md +118 -0
- loop_engineer-0.11.0/docs/integrations/ruflo.md +146 -0
- loop_engineer-0.11.0/docs/superpowers/plans/2026-07-24-event-chain-tamper-evident-provenance.md +1502 -0
- loop_engineer-0.11.0/docs/superpowers/plans/2026-07-25-slice2-verifier-identity-independence.md +1906 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st3-integration-adapters.md +62 -14
- loop_engineer-0.11.0/examples/openhands-certify/README.md +85 -0
- loop_engineer-0.11.0/examples/openhands-certify/certify_run.py +176 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/blocked/base_state.json +54 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/blocked/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/blocked/events/event-00001-b1c2d3e4-0000-4000-8000-00000000ab02.json +9 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/finished/base_state.json +47 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/finished/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +14 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/max-iterations/base_state.json +54 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/max-iterations/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/max-iterations/events/event-00001-b1c2d3e4-0000-4000-8000-00000000ab01.json +9 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/paused/base_state.json +54 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/paused/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/running/base_state.json +54 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/running/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/stuck/base_state.json +54 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/conversations/stuck/events/event-00000-5a1d5379-b1d4-4772-9292-7b002555b529.json +20 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/workspaces/green/artifact.txt +1 -0
- loop_engineer-0.11.0/examples/openhands-certify/fixtures/workspaces/stale/artifact.txt +1 -0
- loop_engineer-0.11.0/examples/ruflo-gate/README.md +82 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.claude-flow/metrics/v3-progress.json +20 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.hive-mind/sessions/hive-mind-prompt-swarm-2026-07-25.txt +13 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-coder-02.json +12 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-coder-03.json +12 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-queen-01.json +12 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/agents/agent-reviewer-04.json +12 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/coordination/consensus-2026-07-25T09-31-52Z.json +17 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/memory-export.json +48 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/state.json +9 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-001-spec.json +9 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-002-implement.json +9 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-003-logging.json +9 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/.swarm/tasks/task-004-review.json +9 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/dedupe-report.json +10 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/dedupe.log +16 -0
- loop_engineer-0.11.0/examples/ruflo-gate/fixture/src/import_contacts.py +24 -0
- loop_engineer-0.11.0/examples/ruflo-gate/swarm_example.py +321 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/__main__.py +29 -1
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/completion.py +22 -3
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/contract.py +344 -3
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/emit.py +204 -2
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/events.py +19 -7
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/evidence.py +148 -10
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/integrations.py +8 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/paths.py +7 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/reducer.py +26 -1
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/runner.py +112 -8
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/runtime.py +134 -13
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/simulate.py +4 -7
- loop_engineer-0.11.0/loop/verifier.py +148 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/pyproject.toml +1 -1
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/repo-os-contract.md +482 -16
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/safety-and-approvals.md +4 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/event.schema.json +3 -3
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/evidence.schema.json +16 -3
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/tasks.schema.json +5 -1
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/terminal.schema.json +4 -1
- loop_engineer-0.11.0/scripts/ci_anchor_probe.py +83 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/metrics.py +29 -3
- loop_engineer-0.11.0/scripts/test_adversarial_evidence_binding.py +540 -0
- loop_engineer-0.11.0/scripts/test_adversarial_verifier_identity.py +268 -0
- loop_engineer-0.11.0/scripts/test_bound_artifact_view.py +233 -0
- loop_engineer-0.11.0/scripts/test_ci_anchor_probe.py +53 -0
- loop_engineer-0.11.0/scripts/test_completion_verdict.py +258 -0
- loop_engineer-0.11.0/scripts/test_completion_verified_evidence.py +366 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_conformance.py +141 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_version.py +2 -2
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_doctor_eventstore.py +106 -2
- loop_engineer-0.11.0/scripts/test_doctor_evidence.py +147 -0
- loop_engineer-0.11.0/scripts/test_doctor_evidence_binding.py +189 -0
- loop_engineer-0.11.0/scripts/test_doctor_evidence_verification.py +211 -0
- loop_engineer-0.11.0/scripts/test_doctor_store_read_guard.py +55 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_event_chain.py +125 -2
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_evidence.py +103 -1
- loop_engineer-0.11.0/scripts/test_evidence_binding_runner.py +139 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_cli.py +1 -1
- loop_engineer-0.11.0/scripts/test_metrics_verifier_source.py +100 -0
- loop_engineer-0.11.0/scripts/test_openhands_recipe.py +205 -0
- loop_engineer-0.11.0/scripts/test_openhands_sdk_drift.py +75 -0
- loop_engineer-0.11.0/scripts/test_ruflo_recipe.py +199 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_runner_dispatch.py +111 -1
- loop_engineer-0.11.0/scripts/test_verifier_identity.py +180 -0
- loop_engineer-0.11.0/scripts/test_verify_evidence_object_collision.py +67 -0
- loop_engineer-0.11.0/scripts/test_verify_evidence_objects.py +150 -0
- loop_engineer-0.11.0/scripts/test_verify_evidence_writer.py +185 -0
- loop_engineer-0.10.0/.github/workflows/ci.yml +0 -113
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.claude-plugin/marketplace.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.github/dependabot.yml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.gitignore +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/.pre-commit-hooks.yaml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/CODE_OF_CONDUCT.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/CONTRIBUTING.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/GLOSSARY.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/LICENSE +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/SECURITY.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/ROADMAP-v1.0.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/adr/0001-proof-kernel-and-runtime.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/01-good-first-qw9-trigger-phrases.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/02-good-first-qw10-self-eval-labels.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/03-good-first-emit-metrics-vocabulary.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/04-help-wanted-openhands-recipe.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/05-help-wanted-ruflo-recipe.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/06-help-wanted-gap-reports.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/contributing/issues/07-help-wanted-emit-scaffold-runlog-seed.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/demo.cast +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/demo.gif +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/gap-reports/superpowers.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/integrations/langgraph.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/integrations/temporal.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/metrics-baseline.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/social-card.png +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-20-loop-engineer-v1.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-30-loop-engineer-v1.0-roadmap.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-03-adoption-slices.md +0 -0
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-09-st5-harness-scoreboard.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-20-loop-engineer-design.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st1-metrics-baseline.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st2-portable-contract-spec.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-v04-credibility-enforcement.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-03-adoption-slices-design.md +0 -0
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-09-st5-harness-scoreboard-design.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/evals/cases/structural.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/evals/rubric.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/mission.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/roadmap.md +0 -0
- {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
- {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
- {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
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/backend/data-imports.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/index.yml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad/bmm/config.yaml +0 -0
- {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
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/sprint-status.yaml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/epics.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/prd.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/src/import_contacts.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/bmad-run/tests/test_import_contacts.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235-analysis.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/epic.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/execution-status.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/github-mapping.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/progress.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/stream-A.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/prds/csv-dedupe.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ccpm-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/approvals/.gitkeep +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-run.txt +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-verdict.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T1.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2-iter1.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/checkpoints/.gitkeep +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/manifest.yaml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/memory/.gitkeep +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/repair/iter-002.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/ADR.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/RUNLOG.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/SPEC.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/TASKS.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/WORKFLOW.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/run-example +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-fast +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-full +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/manifest.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/measure_coverage.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/pricing.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_holdout.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_visible.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/coverage-repair/terminal_state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/absolute-uri.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/bad-sha256-pattern.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/missing-required-field.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/invalid/scheme-uri.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/evidence/valid-evidence.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/holdout-verdict.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1-iter1.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/manifest.yaml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/repair/iter-002.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/terminal_state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/RUNLOG.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/SPEC.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/TASKS.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/WORKFLOW.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/run-example +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-fast +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-full +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/jobs.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/manifest.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/measure_stability.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_holdout.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_visible.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/langgraph-emit/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/langgraph-emit/graph_example.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/naive-loop/.loop/state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/naive-loop/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/README.md +0 -0
- {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
- {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
- {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
- {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
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/config.yaml +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/specs/csv-dedupe/spec.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/plans/coverage-repair.plan.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/plans/invalid/cyclic-dependency.plan.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/plans/invalid/missing-goal.plan.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/plans/completed/csv-dedupe.plan.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/prds/csv-dedupe.prd.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reports/csv-dedupe-report.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-cycle-0.verdict.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-review.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.run.log +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/prp-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/swarm-activity.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/v3-progress.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/security/audit-status.json +0 -0
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.mcp.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/.swarm/memory-export.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/ruflo-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/feature.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/memory/constitution.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/checklists/requirements.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/plan.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/quickstart.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/research.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/spec.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/tasks.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/.superpowers/sdd/progress.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/superpowers-run/docs/superpowers/plans/2026-07-08-csv-dedupe.md +0 -0
- {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
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/config.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/docs/prd.txt +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/reports/task-complexity-report.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/state.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/task_001.txt +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/tasks.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/templates/example_prd.txt +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/CLAUDE.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/task-master-run/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/temporal-certify/README.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/examples/temporal-certify/workflow_example.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/hooks/stop_firewall.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/__init__.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/_resources.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/architect.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/chain.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/foreign.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/fsm.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/migrate.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/plan.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/runcontrol.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/loop/scaffold.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/architecture-matrix.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/eval-suite.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/loop-patterns.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/model-routing.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/platform-map.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/reference/prompt-templates.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/manifest.schema.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/plan.schema.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/receipt.schema.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/repair-record.schema.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/rollout-record.schema.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/schemas/state.schema.json +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/action_scorecard.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/anticheat_scan.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/benchmark_harness.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/chain_fixtures.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/holdout_gate.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/inspect_loop.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/rollout_ledger.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/runtime_monitor.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/self_eval.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_action_scorecard.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_adversarial_chain.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_adversarial_kernel.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_adversarial_process.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_anticheat_scan.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_benchmark_harness.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_ci_release_mode.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_completion_policy.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_contract_records.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_adoption.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_baseline.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_docs_claims.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_emit.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_eventstore.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_example_runnable.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_flaky_example.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_foreign_inspect.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_fsm.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_holdout_gate.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_inspect_loop.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_integrations.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe_st3.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_architect_cli.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_cli.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_cli_status_replay.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_contract_core.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_runcontrol_cli.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_zero_writes.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_manifest_extra_states_schema.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_metrics.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_metrics_cli.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_migrate_cli.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_plan_schema.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_precommit_hook.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_reducer.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_resources.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_rollout_ledger.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_runner_verifier.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_runtime_monitor.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_scaffold.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_schemas_metrics.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_self_eval.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_state_vocabulary.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_stop_firewall.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_template_roundtrip.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_temporal_recipe.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_validate_frontmatter.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/test_wheel_selfcontained.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/scripts/validate_frontmatter.py +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-architect/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-contract/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-engineer/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-evals/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-flywheel/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-inspector/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-inspector/reference/patterns.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-repair/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-run/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/SKILL.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/reference/patterns.md +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/AGENTS.md.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/EVALS-rubric.md.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/RUNLOG.md.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/SPEC.md.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/TASKS.json.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/WORKFLOW.md.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/extract-trace-metrics.sh +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/judge-rubric.sh +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/manifest.yaml.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/state.json.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/terminal_state.json.tmpl +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/verify-fast.sh +0 -0
- {loop_engineer-0.10.0 → loop_engineer-0.11.0}/templates/verify-full.sh +0 -0
- {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.
|
|
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
|
|
@@ -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.
|
|
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
|
[](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml)
|
|
45
45
|
[](https://www.python.org/downloads/)
|
|
46
46
|
[](LICENSE)
|
|
47
|
-
[](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
|

|
|
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.
|
|
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.
|
|
468
|
-
- Release tag: `v0.
|
|
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
|
[](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.python.org/downloads/)
|
|
7
7
|
[](LICENSE)
|
|
8
|
-
[](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
|

|
|
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.
|
|
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.
|
|
429
|
-
- Release tag: `v0.
|
|
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
|
|
@@ -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)
|
|
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/).
|