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.
- {loop_engineer-0.9.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.9.0 → loop_engineer-0.11.0}/.github/workflows/publish.yml +1 -1
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/CHANGELOG.md +132 -1
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/PKG-INFO +18 -6
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/README.md +17 -5
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/action.yml +43 -2
- {loop_engineer-0.9.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.9.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.9.0 → loop_engineer-0.11.0}/loop/__main__.py +69 -6
- loop_engineer-0.11.0/loop/chain.py +88 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/completion.py +22 -3
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/contract.py +348 -5
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/emit.py +204 -2
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/events.py +103 -10
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/evidence.py +148 -10
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/integrations.py +8 -0
- loop_engineer-0.11.0/loop/migrate.py +45 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/paths.py +7 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/reducer.py +44 -3
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/runcontrol.py +9 -1
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/runner.py +143 -35
- loop_engineer-0.11.0/loop/runtime.py +414 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/simulate.py +4 -7
- loop_engineer-0.11.0/loop/verifier.py +148 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/pyproject.toml +1 -1
- loop_engineer-0.11.0/reference/repo-os-contract.md +1509 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/safety-and-approvals.md +4 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/event.schema.json +4 -2
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/evidence.schema.json +16 -3
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/tasks.schema.json +5 -1
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/terminal.schema.json +4 -1
- loop_engineer-0.11.0/scripts/chain_fixtures.py +66 -0
- loop_engineer-0.11.0/scripts/ci_anchor_probe.py +83 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/metrics.py +29 -3
- loop_engineer-0.11.0/scripts/test_adversarial_chain.py +345 -0
- 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.9.0 → loop_engineer-0.11.0}/scripts/test_conformance.py +141 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_version.py +12 -2
- loop_engineer-0.11.0/scripts/test_doctor_eventstore.py +524 -0
- 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.11.0/scripts/test_event_chain.py +610 -0
- {loop_engineer-0.9.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.9.0 → loop_engineer-0.11.0}/scripts/test_loop_cli.py +1 -1
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_cli_status_replay.py +10 -3
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_cli.py +1 -1
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_simulate_zero_writes.py +28 -3
- loop_engineer-0.11.0/scripts/test_metrics_verifier_source.py +100 -0
- loop_engineer-0.11.0/scripts/test_migrate_cli.py +128 -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.9.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.9.0/.github/workflows/ci.yml +0 -113
- loop_engineer-0.9.0/loop/runtime.py +0 -223
- loop_engineer-0.9.0/reference/repo-os-contract.md +0 -780
- loop_engineer-0.9.0/scripts/test_doctor_eventstore.py +0 -166
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.claude-plugin/marketplace.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.github/dependabot.yml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.gitignore +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/.pre-commit-hooks.yaml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/CODE_OF_CONDUCT.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/CONTRIBUTING.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/GLOSSARY.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/LICENSE +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/SECURITY.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/ROADMAP-v1.0.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/adr/0001-proof-kernel-and-runtime.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/01-good-first-qw9-trigger-phrases.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/02-good-first-qw10-self-eval-labels.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/03-good-first-emit-metrics-vocabulary.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/04-help-wanted-openhands-recipe.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/05-help-wanted-ruflo-recipe.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/06-help-wanted-gap-reports.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/contributing/issues/07-help-wanted-emit-scaffold-runlog-seed.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/demo.cast +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/demo.gif +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/gap-reports/superpowers.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/integrations/langgraph.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/integrations/temporal.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/metrics-baseline.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/social-card.png +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-20-loop-engineer-v1.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-06-30-loop-engineer-v1.0-roadmap.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-03-adoption-slices.md +0 -0
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/plans/2026-07-09-st5-harness-scoreboard.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-20-loop-engineer-design.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st1-metrics-baseline.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-st2-portable-contract-spec.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-06-30-v04-credibility-enforcement.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-03-adoption-slices-design.md +0 -0
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/docs/superpowers/specs/2026-07-09-st5-harness-scoreboard-design.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/evals/cases/structural.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/evals/rubric.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/mission.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/product/roadmap.md +0 -0
- {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
- {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
- {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
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/backend/data-imports.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/agent-os-run/agent-os/standards/index.yml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad/bmm/config.yaml +0 -0
- {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
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/implementation-artifacts/sprint-status.yaml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/epics.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/_bmad-output/planning-artifacts/prd.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/src/import_contacts.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/bmad-run/tests/test_import_contacts.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235-analysis.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/1235.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/epic.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/execution-status.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/github-mapping.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/progress.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/epics/csv-dedupe/updates/1235/stream-A.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/.claude/prds/csv-dedupe.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ccpm-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/approvals/.gitkeep +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-run.txt +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/holdout-verdict.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T1.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2-iter1.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/artifacts/verify-T2.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/checkpoints/.gitkeep +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/manifest.yaml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/memory/.gitkeep +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/repair/iter-002.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/.loop/state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/ADR.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/RUNLOG.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/SPEC.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/TASKS.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/WORKFLOW.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/run-example +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-fast +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/scripts/verify-full +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/manifest.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/measure_coverage.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/pricing.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_holdout.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/target/test_visible.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/coverage-repair/terminal_state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/absolute-uri.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/bad-sha256-pattern.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/missing-required-field.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/invalid/scheme-uri.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/evidence/valid-evidence.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/holdout-verdict.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1-iter1.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/artifacts/verify-T1.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/manifest.yaml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/repair/iter-002.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/.loop/terminal_state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/RUNLOG.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/SPEC.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/TASKS.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/WORKFLOW.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/run-example +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-fast +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/scripts/verify-full +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/jobs.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/manifest.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/measure_stability.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_holdout.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/flaky-test-triage/target/test_visible.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/langgraph-emit/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/langgraph-emit/graph_example.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/naive-loop/.loop/state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/naive-loop/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/README.md +0 -0
- {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
- {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
- {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
- {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
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/config.yaml +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/openspec-run/openspec/specs/csv-dedupe/spec.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/plans/coverage-repair.plan.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/plans/invalid/cyclic-dependency.plan.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/plans/invalid/missing-goal.plan.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/plans/completed/csv-dedupe.plan.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/prds/csv-dedupe.prd.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reports/csv-dedupe-report.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-cycle-0.verdict.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/PRPs/reviews/pr-42-review.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.run.log +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/.claude/prp-loop.state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/prp-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/swarm-activity.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/metrics/v3-progress.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.claude-flow/security/audit-status.json +0 -0
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.mcp.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/.swarm/memory-export.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/ruflo-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/feature.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/.specify/memory/constitution.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/checklists/requirements.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/plan.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/quickstart.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/research.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/spec.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/spec-kit-run/specs/001-csv-dedupe/tasks.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/.superpowers/sdd/progress.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/superpowers-run/docs/superpowers/plans/2026-07-08-csv-dedupe.md +0 -0
- {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
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/config.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/docs/prd.txt +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/reports/task-complexity-report.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/state.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/task_001.txt +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/tasks/tasks.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/.taskmaster/templates/example_prd.txt +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/CLAUDE.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/task-master-run/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/temporal-certify/README.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/examples/temporal-certify/workflow_example.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/hooks/stop_firewall.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/__init__.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/_resources.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/architect.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/foreign.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/fsm.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/plan.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/loop/scaffold.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/architecture-matrix.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/eval-suite.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/loop-patterns.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/model-routing.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/platform-map.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/reference/prompt-templates.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/manifest.schema.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/plan.schema.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/receipt.schema.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/repair-record.schema.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/rollout-record.schema.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/schemas/state.schema.json +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/action_scorecard.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/anticheat_scan.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/benchmark_harness.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/holdout_gate.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/inspect_loop.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/rollout_ledger.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/runtime_monitor.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/self_eval.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_action_scorecard.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_adversarial_kernel.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_adversarial_process.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_anticheat_scan.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_benchmark_harness.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_ci_release_mode.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_completion_policy.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_contract_records.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_adoption.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_baseline.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_docs_claims.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_emit.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_eventstore.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_example_runnable.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_flaky_example.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_foreign_inspect.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_fsm.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_holdout_gate.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_inspect_loop.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_integrations.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_langgraph_recipe_st3.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_architect_cli.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_contract_core.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_loop_runcontrol_cli.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_manifest_extra_states_schema.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_metrics.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_metrics_cli.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_plan_schema.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_precommit_hook.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_reducer.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_resources.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_rollout_ledger.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_runner_verifier.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_runtime_monitor.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_scaffold.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_schemas_metrics.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_self_eval.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_state_vocabulary.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_stop_firewall.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_template_roundtrip.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_temporal_recipe.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_validate_frontmatter.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/test_wheel_selfcontained.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/scripts/validate_frontmatter.py +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-architect/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-contract/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-engineer/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-evals/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-flywheel/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-inspector/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-inspector/reference/patterns.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-repair/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-run/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/SKILL.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/skills/loop-runtime-monitor/reference/patterns.md +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/AGENTS.md.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/EVALS-rubric.md.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/RUNLOG.md.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/SPEC.md.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/TASKS.json.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/WORKFLOW.md.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/extract-trace-metrics.sh +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/judge-rubric.sh +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/manifest.yaml.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/state.json.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/terminal_state.json.tmpl +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/verify-fast.sh +0 -0
- {loop_engineer-0.9.0 → loop_engineer-0.11.0}/templates/verify-full.sh +0 -0
- {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.
|
|
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,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.
|
|
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
|
|
@@ -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
|

|
|
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.
|
|
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.
|
|
464
|
-
- 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>`)
|
|
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
|
[](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
|
|
@@ -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
|

|
|
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.
|
|
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.
|
|
425
|
-
- 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>`)
|
|
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@
|
|
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
|
-
|
|
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)
|
|
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
|
|