Skip to content

Releases: jperdior/engineering-loop

v0.8.0

Choose a tag to compare

@jperdior jperdior released this 07 Sep 08:17
78a2534

Fixes the findings of the second end-to-end run (#14).

  • The telemetry table drops its cost column: session | turns | peak context | wall clock | model.
  • launch.sh names the run log after the main checkout, not the worktree directory.
  • /ship filters the run log on the loop's own delivery-loop: prefix and relays only ticks, pause, escalation, PR and exit.
  • The review's fix wave stays inside the spec's scope; a finding against a host skill or doc the spec did not name is written as a proposal, not applied.
  • /ship always writes the spec with the engine's spec-writing, reading a host spec skill as input for the host's conventions; the loop reads a grammar only ours writes.
  • Every skill says the engine's skills are invoked as /engineering-loop:<name>.
  • /code-review reads the gates from the spec, else the host's AGENTS.md.

Upgrade: /plugin update engineering-loop@engineering-loop, then start a new session.

v0.7.0

Choose a tag to compare

@jperdior jperdior released this 06 Sep 23:49
b0b5717

Fixes the eleven findings of the first end-to-end run (#13).

  • loop/launch.sh starts the loop detached with one plain command; /ship uses it. Log under ~/.local/state/engineering-loop/runs/, ending in delivery-loop: exit N.
  • The bell no longer prints Device not configured when the run is detached.
  • Pre-flight probes gh api repos/<owner/repo> and refuses a token that cannot see the repository, naming the settings file and its GH_TOKEN= line.
  • setup-loop.sh without a TTY names the file and lines to set, and says a Claude Code ! command is not a terminal.
  • The superpowers lookup follows CLAUDE_CONFIG_DIR.
  • The pre-PR telemetry omits the PR row instead of writing an empty cell into the PR body.
  • /ship watches the run log with a monitor and a timer, relays only ticks, pause, escalation, PR and exit, and reads telemetry from the state directory.
  • /spec-writing sizes the spec to the change (**Size:** bounded | full in the TLDR; six sections for bounded), proposes a fix to a host skill in the way rather than arguing around it, and fails a section left to the template.
  • /pre-implement-spec runs one audit agent for a bounded spec, four for a full one, and never builds to audit.

Upgrade: /plugin update engineering-loop@engineering-loop, then start a new session.

v0.6.1

Choose a tag to compare

@jperdior jperdior released this 06 Sep 20:34
12ffa78

/ship is back in the slash-command index

The ship skill's description contained a colon followed by a space inside an unquoted YAML value, which is a parse error; Claude Code drops a skill whose frontmatter does not parse and says nothing, so a fresh session found nine skills and No commands match "/engineering-loop:ship". Every skill description is now a double-quoted scalar, and tests/test-skills-frontmatter.sh parses each one with a strict reader in CI.

PR #12.

v0.6.0

Choose a tag to compare

@jperdior jperdior released this 06 Sep 19:12
84d803d

An independent plugin

Nothing of the engine lives in the host repository. Installing is three lines in Claude Code:

/plugin marketplace add jperdior/engineering-loop
/plugin install engineering-loop@engineering-loop
/plugin install superpowers@claude-plugins-official
  • The loop scripts ship inside the plugin, beside the skills. The loop resolves the repository from the directory it is run in.
  • Your settings live in ~/.config/engineering-loop/loop.env (setup-loop.sh writes the sandbox tokens there); the loop's state — lock, unit directories, the worktrees it creates, the telemetry — under ~/.local/state/engineering-loop/<repo>/.
  • The telemetry leaves the branch: its table goes into the PR body under Sessions.
  • The only local trace in a repository is .claude/worktrees/ in .git/info/exclude, never committed.
  • The sandbox mounts the plugin, and superpowers when installed, read-only and starts the session with --plugin-dir.
  • install.sh is gone, and so is the vendored .loop/.

Upgrade

Delete .loop/, the ten .claude/skills/ symlinks into it and the .loop/ lines in .gitignore; move .loop/loop.env to ~/.config/engineering-loop/loop.env; install the plugin.

PR #11.

v0.5.0

Choose a tag to compare

@jperdior jperdior released this 06 Sep 13:45
8541696

The host contract lives in the spec

The gates, the per-worktree cleanup, the generated paths and the extra denials are facts about the host and change with it. They are no longer configured anywhere: /spec-writing derives them from the host's AGENTS.md / CLAUDE.md into every spec's ## Gates section, the human approves them at gate 1 with the rest of the spec, and the loop reads them from the branch like the phases.

  • parse-ledger.sh --gates and --host cleanup|excludes|denials read the section with the ledger's strictness.
  • The loop refuses a spec that declares no gates, reports where its gates came from in --dry-run, and hands the cleanup to the reclaim and the denials to every session.
  • host.env, host.env.dist and the LOOP_* contract keys are gone; install.sh removes a stale template from hosts.

/ship drives the loop from the chat

Phase B starts the loop detached — its own process group, a log under ~/.loop-runs/ — so the run outlives the chat session and the tool-call timeout, then watches the log and relays each event: a phase built, a pause, an escalation, the PR. The terminal commands remain the overnight-over-SSH option.

/ship checks credentials first

gh auth status, jq, timeout; under LOOP_SANDBOX=1 it runs .loop/setup-loop.sh --show and sends the user to the script for a missing token. It never asks for a token in the chat.

A shorter README

Cut from 345 lines to 125: what it does, install, use, what your repository must state, when it stops, settings, the skills. The internals live in the script headers and the skills.

Upgrade from 0.4.0

Delete .loop/host.env and re-run install.sh. Specs written before this need a ## Gates section before the loop will build them.

PRs #9, #10.

v0.4.0

Choose a tag to compare

@jperdior jperdior released this 06 Sep 12:27
dd20f8b

The host contract is committed, and found out from the host's own docs

LOOP_GATES, LOOP_CLEAN_WORKTREE, LOOP_SIZE_EXCLUDES and LOOP_DENIALS_EXTRA are facts about the repository, the same for everyone who builds in it. They move out of the gitignored .loop/loop.env into a committed .loop/host.env, reviewed like any other file.

  • The loop reads host.env before loop.env; the shell still overrides both. --dry-run reports where the gates came from.
  • There is no default gate. A repository that declares none is refused at pre-flight, naming the file.
  • The agent finds it out. /ship gains a step 0: when host.env is missing or names no gates, it reads the host's AGENTS.md / CLAUDE.md, derives the four values from what the host documents, shows each line beside the sentence it came from, and commits the file on the feature branch. /run-gates derives the gates the same way when the file is missing and says so; it never invents a default.
  • loop.env keeps what is personal: the two sandbox credentials, LOOP_MODEL, LOOP_SANDBOX, the bounds.
  • reclaim-worktree.sh and unit-size.sh read host.env first; install.sh vendors host.env.dist and leaves host.env alone.

Upgrade from 0.3.0

Move the four host lines from .loop/loop.env into a committed .loop/host.env (format in .loop/host.env.dist), or let the next /ship write it. Until then pre-flight refuses with the file's name.

PRs #7, #8.

v0.3.0

Choose a tag to compare

@jperdior jperdior released this 06 Sep 10:46
a1f07a3

A stop keeps the phase

A session refused for the usage limit, killed, or exited without a sentinel leaves its half-built phase uncommitted in the worktree. The loop now records which session it launched before launching it and a re-run continues that session with claude --resume in the worktree it left. A transcript that is gone falls back to a fresh session told the tree holds a predecessor's work. Only the done path reclaims a worktree the loop created; exits 4 and 5 keep it and say so.

  • Builds where it is driven from. From a linked worktree already on the unit's branch, the loop builds in that tree: no second worktree, no checkout, no reclaim. Its state hangs off the main checkout's .loop/state; loop.env is read from the driver first and the main checkout second.
  • One loop per unit, several per repository. The lock is lock/<branch>/, liveness matches the recorded snapshot path, and git worktree add is serialised on a config lock.
  • Named, killable session containers under the sandbox, with a cid the teardown kills by; the container sees the common git directory and the unit's own directory only.
  • A resumed closing step does not repeat the earlier ones.
  • /ship: gate 1 is your spoken OK on the spec in the worktree. No spec PR.

A phase names the host skills it builds through

Each phase's ### Phase N section carries a - **Skills:** line naming the host's own skills the phase must use — its scaffolds, test runners, linters — resolved by /spec-writing from the host's skill index (the router table in the root AGENTS.md, else the descriptions under .claude/skills/). parse-ledger.sh --skills "Phase N" reads it, the loop hands the names to the session as a Skills: prompt line and lists them in --dry-run, /implement-spec invokes them before writing, and /pre-implement-spec fails a name that resolves to nothing.

Upgrade

Re-run install.sh in the host. State moves to .loop/state/units/<branch>/; a pre-0.3 repository-wide lock/pid is respected while alive and swept when dead.

PRs #4, #5, #6.