Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "loop-engineer",
"version": "0.7.0",
"version": "0.8.0",
"description": "Design, launch, verify, repair, and improve agent loops. A Claude-Code-native architect+operator for long-running, verifiable, self-improving agentic-coding systems.",
"author": { "name": "Sollan Systems", "url": "https://github.com/SollanSystems" },
"homepage": "https://github.com/SollanSystems/loop-engineer",
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ Thumbs.db
# Secrets — never commit
.env
*.local

# Local cold-start context — deliberately untracked (see its own do-not-commit note)
/CLAUDE.md
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ All notable changes to `loop-engineer` are documented here.
`WORKFLOW.md` and `README.md` are reworded to describe the mechanism; the 0.3.4
history is left intact.

## Unreleased
## 0.8.0 — 2026-07-09

**ST3 — integration adapters.** `loop/integrations.py`: an engine-neutral,
pure-stdlib projection (`EngineOutcome` + `to_terminal_state`) from any
Expand All @@ -32,6 +32,19 @@ recorded FCR-1.0 follow-up) and a Temporal recipe lands
(visible-green/holdout-red → `FailedUnverifiable` with
`false_completion: true`, never `Succeeded`) and pass the doctor round-trip.

**ST4 — contributor funnel.** `loop inspect` now recognizes a foreign
Superpowers-style run dir read-only (`loop/foreign.py` — a layout mapper onto
the existing `LoopPaths` seam; the M2/M3-hardened scorer is untouched and a
foreign harness with no gate and no terminal record scores honestly low).
The reading is checked in as `docs/gap-reports/superpowers.md` — the §14
conformance checklist evaluated against a vendored, sanitized fixture
(`examples/superpowers-run/`). A second runnable example lands:
`examples/flaky-test-triage/` — doctor-clean, gate-backed, and the showcase
for repair records (`loop metrics` derives a non-null repair-productivity of
1.0 from its anchored red→green repair). Seven gate-backed starter issues are
drafted under `docs/contributing/issues/` and filed at release;
CONTRIBUTING gains the start-here funnel.

## 0.7.0 — 2026-07-08

**ST2 — the portable standard.** The on-disk contract is now a documented,
Expand Down
125 changes: 0 additions & 125 deletions CLAUDE.md

This file was deleted.

19 changes: 19 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ python3 -m loop inspect examples/coverage-repair

If you don't have the deps, prefix with `uv run --with pyyaml --with pytest`.

## Start here — the contributor funnel

Every open starter issue names **the gate that proves the fix** — a
deterministic command that is red before your change and green after. That is
the whole review bar (see the ground rule above).

- [`good first issue`](https://github.com/SollanSystems/loop-engineer/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
— small, bounded, gate-verifiable fixes.
- [`help wanted`](https://github.com/SollanSystems/loop-engineer/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
— integration recipes (OpenHands, ruflo — designs already written in
`docs/superpowers/specs/2026-06-30-st3-integration-adapters.md`) and
foreign-harness gap reports (`docs/gap-reports/`).

The contribution target for anything that emits or consumes contract
artifacts is the standard: `reference/repo-os-contract.md` — a harness that
satisfies the §14 conformance checklist (A1–E1) may claim it emits a
Loop-Engineer-conformant contract v1. Drafts for the seeded issues live in
`docs/contributing/issues/` and are filed on GitHub at release time.

## Repository layout

| Path | What lives here |
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![CI](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/SollanSystems/loop-engineer/actions/workflows/ci.yml)
[![Python 3.10–3.12](https://img.shields.io/badge/python-3.10%E2%80%933.12-blue)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![Release](https://img.shields.io/badge/release-0.7.0-blue)](https://github.com/SollanSystems/loop-engineer/tags)
[![Release](https://img.shields.io/badge/release-0.8.0-blue)](https://github.com/SollanSystems/loop-engineer/tags)

Long-running agents commit **false completion**. After context compaction they
forget what "done" meant, optimize to the visible test, patch in circles, and
Expand Down Expand Up @@ -307,7 +307,7 @@ refuses an evidence-free `Succeeded` at write time. Recipe:
**CI** — one workflow step validates the contract and publishes a scorecard:

```yaml
- uses: SollanSystems/loop-engineer@v0.7.0
- uses: SollanSystems/loop-engineer@v0.8.0
with:
path: "."
```
Expand Down Expand Up @@ -397,12 +397,12 @@ license, and README differentiation.

## Status

- Version: `0.7.0`
- Release tag: `v0.7.0` (PyPI publish trigger; plugin tags through 0.6.0 used `loop-engineer--v<version>`)
- Version: `0.8.0`
- Release tag: `v0.8.0` (PyPI publish trigger; plugin tags through 0.6.0 used `loop-engineer--v<version>`)
- License: MIT
- Primary interface: Claude Code plugin
- Portable core: Python CLI + JSON schemas
- Current reference example: `examples/coverage-repair`
- Current reference examples: `examples/coverage-repair`, `examples/flaky-test-triage`

---

Expand Down
45 changes: 45 additions & 0 deletions docs/contributing/issues/01-good-first-qw9-trigger-phrases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!-- title: Trigger-phrase disambiguation batch (3 LOW fixes) -->
<!-- labels: good first issue -->

# Trigger-phrase disambiguation batch (3 LOW fixes)

Three small `SKILL.md` frontmatter edits that sharpen router resolution. Each is
independently checkable and none changes behavior — only the trigger prose.

## Problem

Three trigger-phrase weaknesses, all present at this commit:

- **Shared bare "grade" verb.** `skills/loop-evals/SKILL.md` anchors *"or grade a
long-running agentic run"* and `skills/loop-inspector/SKILL.md` anchors *"grade a
superpowers / ruflo / .loop harness"* — both hang the same verb on different
objects, so a bare "grade this" query has no clean winner.
- **`loop-evals` verbosity outlier.** Its `description` scalar runs well past the
sibling band (~736 chars vs a ~400–510-char peer range), because capability prose
(the 7-layer suite, deterministic-then-rubric, the regression harness) lives in the
frontmatter instead of the body.
- **`loop-run` weak first example.** `skills/loop-run/SKILL.md` opens its example
list with bare `'run the loop'` — the only one of its examples lacking a
qualifier.

## Proposal

- Make the noun part of each "grade" phrase: evals → *"grade a run's outcome against
its SPEC"*; inspector → *"grade this harness/contract's readiness"*.
- Trim `loop-evals`' `description` into the ~400–510-char sibling band by moving the
capability-summary prose into the skill body, leaving trigger phrases + a one-line
hook in frontmatter.
- Qualify `loop-run`'s opening example: *"run the agent loop"* (or *"run this loop's
state machine"*).

Keep every `description` a *quoted* YAML scalar (the suite quotes all of them).

## The gate that proves the fix

```bash
python3 scripts/validate_frontmatter.py # green
python3 scripts/self_eval.py # green
```

`loop-evals`' frontmatter length should land back in the sibling band; the two
gates above are the whole review bar.
39 changes: 39 additions & 0 deletions docs/contributing/issues/02-good-first-qw10-self-eval-labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!-- title: Label self_eval terminal/repair/eval checks honestly as doc-completeness -->
<!-- labels: good first issue -->

# Label self_eval terminal/repair/eval checks honestly as doc-completeness

A naming/comment clarification (no behavioral change required) that keeps the gate
honest about its own scope.

## Problem

Three `scripts/self_eval.py` checks are substring-presence scans over a single
`SKILL.md` each, not behavioral enforcement:

- `check_terminal_states` (`scripts/self_eval.py:185`) — `missing = [s for s in
facts["terminal_states"] if s not in text]` over `skills/loop-run/SKILL.md`.
- `check_repair_fields` (`scripts/self_eval.py:193`) — same shape over
`skills/loop-repair/SKILL.md`.
- `check_eval_layers_and_metrics` (`scripts/self_eval.py:206`) — normalized
substring presence over `skills/loop-evals/SKILL.md`.

Each passes as long as the canonical words *appear in the prose*. Presenting them as
"the hard pass/fail gate" risks a reader mistaking documentation-completeness for
runtime-correctness enforcement — gaming requires only listing the canonical words.

## Proposal

Rename and/or comment the three checks as **documentation-completeness** checks (not
behavioral enforcement), and say so where `self_eval` is described as a gate — in
`CONTRIBUTING.md` (the "Ground rule" / self_eval mention) and in the README's
structural-check list. No behavioral change is required if the checks are
intentional; this is a scope-honesty clarification consistent with the suite's own
posture.

## The gate that proves the fix

```bash
python3 scripts/self_eval.py # green (13 structural invariants)
python3 -m pytest -q scripts/test_docs_claims.py # README accuracy assertions green
```
44 changes: 44 additions & 0 deletions docs/contributing/issues/03-good-first-emit-metrics-vocabulary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- title: Reconcile emit's iteration-outcome vocabulary with metrics' recognized tokens -->
<!-- labels: good first issue -->

# Reconcile emit's iteration-outcome vocabulary with metrics' recognized tokens

The writer and the metrics reader disagree on the outcome vocabulary, so a RUNLOG
written entirely through the sanctioned writer can still look "dirty" to `loop
metrics`.

## Problem

`loop/emit.py` `_ITERATION_OUTCOMES` (`loop/emit.py:26`) accepts `approval_requested`
and `replanned`, but `scripts/metrics.py` `_KNOWN_OUTCOME_TOKENS`
(`scripts/metrics.py:101`, built from `_SUCCESS_OUTCOME_TOKENS` +
`_HONEST_RED_OUTCOME_TOKENS`) recognizes neither. So an iteration appended via
`emit.append_iteration(..., outcome="approval_requested")` — a fully valid write —
surfaces under `provenance.unrecognized_outcomes`.

Checkable at this commit:

```python
import sys; sys.path.insert(0, "scripts"); import metrics
from loop.emit import _ITERATION_OUTCOMES
print([o for o in _ITERATION_OUTCOMES if o not in metrics._KNOWN_OUTCOME_TOKENS])
# -> ['approval_requested', 'replanned']
```

## Proposal

Decide the canonical vocabulary and align the two ends:

- either add `approval_requested` and `replanned` to metrics' honest-red set
(`scripts/metrics.py` `_HONEST_RED_OUTCOME_TOKENS`) — they are known, non-success
outcomes, so they belong there and should not read as "unrecognized synonyms";
- or narrow `emit`'s accepted set to the tokens metrics already knows.

Add a round-trip regression test: `emit.append_iteration` writing every allowed
outcome, then `compute_metrics(...)` reports `provenance.unrecognized_outcomes == []`.

## The gate that proves the fix

```bash
python3 -m pytest scripts/test_metrics.py scripts/test_emit.py # green
```
Loading
Loading