Skip to content

Repository files navigation

Engineering Loop

Go orchestrator for a strong-model/cheap-model engineering workflow using the akvarel/jcode fork.

Campaign Autopilot

Turn a short outcome into an executable, independently verified engineering campaign:

eloop do "add a tested health check"
eloop do "add a tested health check" --plan-only
eloop autopilot "improve API reliability and close the verified follow-up work"
eloop campaign status <campaign-id>
eloop campaign continue <campaign-id>
eloop campaign stop <campaign-id>

Campaigns are stored atomically under engineering-campaigns/<campaign-id>/. Each task is compiled from Git, repository instructions, build files, prior eloop findings, review bundles, unresolved campaign tasks, and available tools. A separate critic may correct the task before execution. Completion requires local command evidence and a separately routed verifier approval.

Autopilot is bounded by task, per-task retry, failure, cost, and active-runtime limits. Queue waiting, terminal pauses, and time awaiting an explicit campaign continue do not consume the runtime budget. Planning, model calls, verification, and executor activity do consume it. A task that does not succeed immediately is persisted as DEFERRED; independent ready tasks continue first, then the deferred goal is recompiled from fresh repository context and retried. Dependencies and all safety gates remain enforced. Explicit development, test, and staging deployments may proceed when the contract prohibits production access and identifies the target environment; pre-provisioned environment secrets may be consumed but never read, printed, rotated, or replaced. Production or ambiguous deployment/publication, missing secret input, data migration, destructive operations, degraded mandatory verification, scope violations, dirty repositories, and repeated task fingerprints remain blocked by default.

See docs/MANUAL.md for configuration, artifacts, recovery, and troubleshooting.

Compiler recovery can safely replay a previously saved model response after a parser compatibility fix when Git HEAD, status, and diff are unchanged. The response still passes strict contract validation and the independent critic; cached prose annotations never grant execution authority.

MVP flow

task.md → jcode run --ndjson → test/build/lint → git patch → review-bundle.zip

The web ChatGPT account is intentionally not automated. Upload review-bundle.zip to the strong model and use prompts/reviewer.md. Save its correction package as a new task and run again.

Build

go build -o eloop ./cmd/eloop
go test ./...

Initialize a target repository

Copy the eloop binary into PATH, then from the repository root:

eloop init
cp config.example.yaml eloop.yaml # when using this source tree

Edit eloop.yaml for your JCode provider/model and project commands.

Run

Use a clean Git branch and working tree:

eloop run task.md

Artifacts:

.engineering-loop/runs/<timestamp>/
  input/task.md
  input/combined-prompt.md
  logs/jcode.ndjson
  logs/jcode.stderr.log
  logs/test.log
  logs/build.log
  logs/lint.log
  changes.patch
  changed-files.txt
  metadata.json
  review-bundle.zip

To deliberately start with local changes:

eloop run --allow-dirty task.md

The tool never commits, pushes, resets, or cleans the repository.

v0.2.0

  • Streams readable progress from JCode NDJSON.
  • Creates a temporary Git baseline commit for --allow-dirty; review patches contain only changes made after the run starts.
  • Auto-detects Maven, Gradle, or Go verification commands when configured as auto.
  • Extracts the final agent response to final-report.md.
  • Ignores .engineering-loop/ by default.

For Maven projects, auto resolves to mvn test and mvn package -DskipTests (or ./mvnw).

Profile-based execution and review (v0.7.0)

There is no special agent, weak_model, medium_model, or strong_model section. Every model command is a freely named profile, and pipeline roles select profiles.

profiles:
  qwen:
    command: jcode
    arguments: ["--provider", "ollama", "--model", "qwen3-coder"]

  sonnet:
    command: jcode
    arguments: ["--provider", "anthropic", "--model", "REPLACE_MODEL"]

  judge:
    command: jcode
    arguments: ["--provider", "openrouter", "--model", "REPLACE_MODEL"]

pipeline:
  executor: qwen
  investigator: qwen
  dependency: sonnet
  adversarial: sonnet
  consensus: judge
  consensus_fallback: sonnet

pipeline.consensus_fallback is optional. If omitted and consensus fails, the run is marked degraded.

Run from any directory inside the target Git repository:

/path/to/eloop review task.md

Configuration discovery priority:

  1. --config;
  2. eloop.yaml in the current directory or a parent directory;
  3. ~/.config/eloop/config.yaml;
  4. built-in local Ollama defaults.

Review prompts

eloop review does not keep Graphify, Memory, or AGENTS instructions inside Go source code. It loads these required files from prompts.directory:

  • preflight.md
  • graphify.md
  • memory.md
  • investigator.md
  • dependency.md
  • adversarial.md
  • consensus.md

Relative prompts.directory paths are resolved from the directory containing the discovered eloop.yaml. This lets each repository version its own review policy while the eloop binary can live anywhere.

Run eloop init in a repository to create the default configuration and all prompt files. A missing or empty required review prompt is a fatal configuration error; eloop will not silently use an embedded replacement.

Reproducible review bundles (v0.7.0)

Every review run now embeds the exact source prompts under prompts/ and the fully assembled prompts sent to each reviewer under effective-prompts/. The bundle no longer depends on the original prompt directory being present later.

Revalidate a completed review

When a model produced a complete consensus but an older eloop quality gate rejected harmless additive metadata, reprocess the saved run without calling any model:

eloop revalidate engineering-review/runs/<timestamp>

This rewrites output/final-report.md, output/findings.json, adds output/revalidation.json, and rebuilds output/review-bundle.zip. Historical logs and the original validation error remain preserved.

Consensus quality gate (v0.8.3)

A consensus process exit code is no longer treated as proof that the review succeeded. The consensus prompt must end with the ELOOP_FINDINGS_JSON contract documented in prompts/consensus.md. eloop validates the human report and the semantic JSON contract. Additive metadata fields are ignored for forward compatibility, while all required fields and values remain strictly validated.

The primary consensus is rejected when, for example:

  • the machine-readable markers or required fields are missing;
  • required JSON fields are missing or classifications are invalid;
  • confidence is outside 0–100;
  • no evidence-backed findings or next executable task are present;
  • the human report is empty or missing required sections.

When validation fails, pipeline.consensus_fallback is invoked even if the primary model exited with code 0. The bundle preserves:

consensus/consensus-primary.md
consensus/consensus-fallback.md   # when used
consensus/consensus.md            # selected raw response
output/final-report.md            # cleaned human report
output/findings.json              # validated structured result

metadata.json records the validation result and exact fallback reason. Existing repositories upgrading from v0.7 must replace or merge prompts/consensus.md so it contains the v0.8 output contract.

v0.8.1 compatibility fix

Consensus JSON may contain harmless additive metadata such as eloop_version or generated_at. These fields no longer invalidate an otherwise correct report. Unknown fields are discarded from output/findings.json; missing required fields, invalid classifications, malformed JSON, and invalid confidence values still fail the quality gate.

v0.8.2 confidence compatibility fix

root_cause_confidence is normalized to an integer percentage. The parser accepts the canonical integer form (95), fractional probability form (0.95), and string equivalents such as "95%". Canonical output/findings.json always contains an integer percentage. Existing runs can be repaired with eloop revalidate <run-dir> without invoking a model.

v0.8.3 environment status compatibility fix

The consensus parser now normalizes common equivalent environment status values. For example, full, FULL_ENVIRONMENT, and complete become canonical FULL; degraded, partial, and limited environment become canonical DEGRADED_ENVIRONMENT. Unknown semantic values still fail validation.

v0.8.4 consensus schema adapter

The parser now accepts HEALTHY, AVAILABLE, and similar positive aliases as canonical FULL, while degraded or limited aliases remain DEGRADED_ENVIRONMENT. It also adapts the bug-oriented consensus shape emitted by some models (primary_bug and secondary_bugs) into canonical root_cause and findings entries. When next_executable_task is absent from the JSON block, it is recovered from the human Markdown section without being truncated by shell comments inside fenced code blocks.

The generated consensus prompt now explicitly requires the canonical keys and instructs models to place richer details inside the findings array. The adapter is a recovery mechanism; newly generated reports should still follow the canonical schema.

v0.9.0 model token usage reports

Every eloop run and eloop review now parses the saved JCode NDJSON token events and writes:

  • token-usage.md — human-readable totals by stage and by provider/model;
  • token-usage.json — machine-readable usage details.

Review runs place these files under output/. Implementation runs place them in the run directory. eloop revalidate also regenerates the usage report from existing logs without calling a model.

For any existing run directory:

eloop usage engineering-review/runs/<timestamp>

The report contains request count, total input, cached input, cache-creation input, uncached/missed input, and output tokens. JCode emits input as total input in its token events, so eloop calculates:

input_missed = max(input_total - input_cached, 0)

The final done.usage object is ignored when explicit type=tokens events exist, because JCode repeats the last usage there.

About

Full engineering loop for jcode or any other agents

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages