OpenJCockpit

A spec-driven delivery platform where AI agents turn a written requirement into a reviewable pull request — plan first, code second — while every action stays gated by policy and human review.

About

The OpenJCockpit is a multi-module application that lets a team drive feature work through AI agents without losing the standard review discipline of a normal engineering workflow. Instead of an agent pushing straight to a branch, every run produces specs, plans, and code changes as ordinary pull requests that a human still reviews and merges.

Dashboard

React/Vite frontend (frontend/apps/dashboard) — projects, workflow design, and live run logs, secured with Keycloak.

ai-control-service

OpenAPI-first Spring Boot API (services/ai-control-service) — the contract-driven front door for projects, credentials, and workflows.

embabel-agent-service

The management plane (services/embabel-agent-service): workflows and their orchestration, the agent catalogue, tenant bindings, approval gates, OPA policy decisions and run history.

embabel-agent-runtime

The execution plane (services/embabel-agent-runtime): the Embabel agent runtime that runs configuration-driven agents, their LLM calls and tools, and serves them over A2A — an independently deployable container.

git-mcp-server

A Spring AI MCP server (services/git-mcp-server) exposing git operations (branch, commit, push, PR) as tools, called only through a policy-gated gateway.

Spec-driven, not vibes-driven

Every feature lives as its own folder under specs/ (NNN-feature-slug) with spec.md, plan.md, tasks.md, and review.md. Four default workflows drive the pipeline end to end:

WorkflowIdProduces
Spec folder initializationwf-spec-initPR adding the .specify template structure
Create spec from prompt (RAG)wf-spec-createPR with a new spec file under specs/
Implement specwf-spec-implementPR with a plan only — no code changes
Realize spec (code)wf-spec-realisePR with the actual code changes (reuses an existing plan if one was already merged)

Because git publishing is deterministic — handled by the service itself rather than left to the model — every run ends in a real branch and pull request, regardless of how closely the LLM output follows instructions.

Security by default

Access to the dashboard requires a valid Keycloak token (Authorization Code + PKCE). Every tool call an agent makes — including all git operations — passes through a policy-guarded MCP gateway before it is allowed to run, so agents only ever get the least privilege they need.

Spec queue

Each project has one queue of specs that the runner works through one at a time. Item statuses: QUEUED, STARTING, RUNNING, AWAITING_MERGE, MERGING, MERGED, COMPLETED_NO_CHANGES, FAILED, SKIPPED, CANCELLED, REMOVED. Queue states: ACTIVE, PAUSED, HALTED. Users can enqueue, edit, reorder, cancel or remove items, retry or skip a failed item, and pause or resume the queue. A failed item halts the queue; retry or skip it (or remove it), then resume the queue.

Auto-merge risk

With auto-merge, a pull request is merged without a human review once its checks pass. It is off per item by default and requires the admin-only project setting autoMergeAllowed (role openjcockpit-admin).

Poll errors

EMBABEL_UNAVAILABLE, EMBABEL_UNAUTHORIZED, RUNNER_NOT_CONFIGURED, GITHUB_UNAVAILABLE, PREFLIGHT_UNAVAILABLE, GITHUB_RATE_LIMITED.

Failure reasons

WORKFLOW_INVALID, PREFLIGHT_FAILED, START_REJECTED, START_OUTCOME_UNKNOWN, RUN_FAILED, RUN_CANCELLED, APPROVAL_DENIED, RUN_BLOCKED, RUN_TIMED_OUT, RUN_STATE_LOST, PR_NOT_CREATED, PUBLICATION_FAILED, PR_URL_INVALID, PR_HOST_UNSUPPORTED, PR_CLOSED_UNMERGED, MERGE_CONFLICT, MERGE_BLOCKED, MERGE_WAIT_TIMEOUT, MERGE_AUTH_FAILED, MERGE_OUTCOME_UNKNOWN.

Known limits

One item is active per project. Merging is GitHub-only, and only an item with exactly one pull request can be auto-merged. A merge request is sent at most once; an unclear outcome is decided by a read. A start whose outcome is unknown fails the item and halts the queue, because the runner cannot stop a run it may have started.

Tutorial: your first project and workflow run

This walks through running the platform locally with Docker Compose, connecting a repository, and letting the pipeline open its first pull request.

  1. Prerequisites

    You'll need:

    • Docker and Docker Compose
    • An OpenAI API key for the agents
    • A GitHub personal access token with repo access, for the repository you want the pipeline to work on
    • Ollama installed and running on your host machine, with the qwen3.6:27b model pulled (ollama pull qwen3.6:27b) — it serves the pipeline's default local LLM and is not part of the Docker Compose stack; the pipeline now reaches Ollama through the in-stack LiteLLM gateway rather than calling it directly
  2. Configure your environment

    From the repository root:

    cp .env.example .env
    # edit .env and set OPENAI_API_KEY

    Optionally set OLLAMA_BASE_URL and OLLAMA_MODEL in .env to point the pipeline at a differently located Ollama daemon or model tag; both have working defaults, see the project README.md.

  3. Start the stack

    docker compose up --build

    Once the containers are healthy, open:

    • http://localhost:4000 — the dashboard
    • http://localhost:8080/admin — Keycloak admin console
    • http://localhost:4100 — LiteLLM gateway admin UI (local-only credentials)

    The dashboard redirects to a custom Keycloak login page. Sign in with one of the seeded local users (e.g. ricky / Welkom01!) — see the project README.md for the full list.

    For the full LiteLLM variable table, both revert paths, and the local-only credential warning, see the project README.md.

  4. Add your project

    In the dashboard, create a project pointing at the git repository you want the pipeline to operate on, and add a git credential (your personal access token) under Settings → Git credentials. The pipeline uses this repository URL and credential for every workflow run against this project.

  5. Initialize the spec structure

    If the target repository has no .specify folder yet, the dashboard shows a prompt to run the spec-init workflow. Starting it opens a pull request that adds the spec template structure to the repository. Merge that PR before continuing.

  6. Create your first spec

    Once .specify exists, the dashboard shows the ✨ Create spec with prompt button. Click it and describe the feature you want in plain language — this starts the Create spec from prompt (RAG) workflow, which writes a small, self-contained spec file under specs/ and opens it as a pull request. Review and merge it.

  7. Run the workflow

    Select the merged spec file and start Realize spec (code). The pipeline runs impact analysis, test design, an implementation plan, and a review, then generates the actual file changes and opens a pull request on a feat/<workflow-id>-<run-id> branch. Watch progress live in the run's agent log console.

    Prefer a plan you approve separately first? Run Implement spec instead, merge its plan-only PR, then start Realize spec (code) — it will find and reuse the merged plan rather than generating a new one.
  8. Review and merge

    Treat the generated pull request like any other: review the diff, run your existing CI checks, and merge when it's ready. The agent never merges on its own — that decision always stays with your team.