Metadata-Version: 2.4
Name: joshua-agent
Version: 2.1.0
Summary: Security-first multi-model AI release control plane with risk-tiered PR automation, bounded Specs, technology skills, fenced jobs, and least-privilege tools.
Author-email: Jorge Vazquez <jorgevazquez-vagojo@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/jorgevazquez-vagojo/joshua-agent
Project-URL: Documentation, https://github.com/jorgevazquez-vagojo/joshua-agent#readme
Project-URL: Repository, https://github.com/jorgevazquez-vagojo/joshua-agent
Project-URL: Issues, https://github.com/jorgevazquez-vagojo/joshua-agent/issues
Keywords: ai,agents,autonomous,multi-agent,multi-model,sprint,llm,claude,codex,aider,opencode,skills,specifications,salesforce,adobe,quality-gate,github,ci,pull-request,auto-merge,risk,evidence,mcp,sandbox,least-privilege,evaluation,shadow-mode,model-routing,control-plane,fleet,leases,marketplace,ed25519,supply-chain
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Information Technology
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Office/Business
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31
Requires-Dist: pydantic>=2.0
Requires-Dist: rich>=13.0
Requires-Dist: cryptography>=44.0
Provides-Extra: redis
Requires-Dist: redis>=5.0; extra == "redis"
Provides-Extra: server
Requires-Dist: fastapi>=0.115; extra == "server"
Requires-Dist: uvicorn>=0.32; extra == "server"
Provides-Extra: all
Requires-Dist: redis>=5.0; extra == "all"
Requires-Dist: fastapi>=0.115; extra == "all"
Requires-Dist: uvicorn>=0.32; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: fastapi>=0.115; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: uvicorn>=0.32; extra == "dev"
Requires-Dist: bandit>=1.7; extra == "dev"
Requires-Dist: pip-audit>=2.7; extra == "dev"
Dynamic: license-file

# joshua-agent

[![PyPI](https://img.shields.io/pypi/v/joshua-agent?color=blue&label=pypi)](https://pypi.org/project/joshua-agent/) [![Python](https://img.shields.io/pypi/pyversions/joshua-agent)](https://pypi.org/project/joshua-agent/) [![CI](https://github.com/jorgevazquez-vagojo/joshua-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/jorgevazquez-vagojo/joshua-agent/actions/workflows/ci.yml) [![Tests](https://img.shields.io/badge/tests-818%20passing-brightgreen)](#current-status) [![License: MIT](https://img.shields.io/github/license/jorgevazquez-vagojo/joshua-agent?color=green)](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/LICENSE) [![Downloads](https://img.shields.io/pypi/dm/joshua-agent?label=downloads&color=blue)](https://pypi.org/project/joshua-agent/) [![Stars](https://img.shields.io/github/stars/jorgevazquez-vagojo/joshua-agent?style=social)](https://github.com/jorgevazquez-vagojo/joshua-agent)

**A security-first AI release control plane.** Agents implement and review in cycles; the gate deploys on GO, flags CAUTION, and rolls back on REVERT. Run one repo locally or coordinate a fenced fleet from the v2 dashboard.

```
pip install joshua-agent
```

| | |
| --- | --- |
| **Version** | `2.1.0` |
| **Tests** | 818 passing · Python 3.11 / 3.12 / 3.13 |
| **Runners** | Claude Code · OpenAI Codex · Aider · OpenCode · any CLI tool |

## What's new (v1.18–v2.1)

- **PR Quality Autopilot (v2.1):** issue acceptance criteria receive stable IDs and an independent gate must attach explicit PASS/FAIL evidence. The final diff gets a deterministic 0–100 risk tier, regression-test/local-command/GitHub-check evidence, and an explainable merge decision. Low-risk PRs can merge through normal branch protection only when configuration and the exact run both grant it; sensitive paths, high/critical risk, head drift, skipped checks, requested changes, or missing evidence retain human review. Merge is fenced to the reviewed full SHA and never uses administrator bypass.

- **Multi-model technology teams + Specs (v2.1):** agents and static subagents can pin different model IDs, delegated agents inherit an explicit parent model and its capability boundary by default, and collaboration metadata records the requested routes. PR auto-merge requires distinct declared implementation/reviewer models by default. Bounded repository Specs are loaded as hashed, secret-redacted, untrusted requirements context. Maintained profiles cover software architecture, Python, TypeScript, PHP, frontend/backend/testing/database, Salesforce, Marketing Cloud, Adobe Analytics, AEP, and Adobe Commerce; a packaged protocol coordinates Architecture, DEV, QA automation, and independent gates.

- **Distributed control plane + signed marketplace (v2.0):** durable idempotent jobs select nodes by label and local config reference, use hashed lease tokens and fresh fencing generations, stop safely on cancellation/lease loss, and disable remote deploy by default. `/ui` is a responsive CSP-locked dashboard. A new offline-first marketplace verifies Ed25519 catalogs/manifests plus every file hash before activating skills, templates, or eval suites. Dedicated node tokens cannot submit work or operate the fleet.

- **Reproducible evals + routing (v1.26):** versioned deterministic suites run in bounded disposable fixtures; prompts/raw responses are never persisted. Shadow challengers are quarantined until exact-run approval, comparisons require the same suite digest, and the conservative router supports off/observe/active modes with confidence, quality-regression, cost, and latency evidence. Active routing fails closed to baseline and uses the selected candidate's cost rate.

- **Least privilege + MCP (v1.25):** every agent now resolves an auditable capability manifest. Gates are read-only by default, delegated agents inherit their parent's boundary, optional Docker mode supplies strong filesystem/network isolation with read-only Git metadata, and Joshua mediates consented MCP `stdio` tools through dual allowlists, policy gates, hard limits, secret-redacted audit, and one bounded evidence round.

- **GitHub Autopilot (v1.24):** turn an issue or failed Actions run into a persisted, bounded repair job and draft PR. Planning is the default; `--execute` explicitly enables a dedicated worktree, gated agent repair, diff policy, local validation, push, PR creation, check monitoring, and at most five configured attempts. It never merges or deploys.

- **Outcome-grounded learning (v1.23):** immutable episodes connect agent work to the final gate, metric, deploy, and rollback result. Only trusted episodic memories reach prompts; every recall is scored, attributable, searchable, and reversible.

- **Core reliability (v1.22):** one runner registry now drives validation, factory dispatch, preflight, `doctor`, and the setup wizard. CLI command collisions are removed, the first command modules have been extracted from `cli.py`, and the entire codebase passes full Ruff checks.

- **OpenCode runner (v1.21):** use `runner.type: opencode` for non-interactive OpenCode sprints, including model/binary overrides, sandboxed OpenCode environment variables, CLI preflight, and setup-wizard support.

- **Hardened release gate (v1.17):** multi-gate consensus is now *most-restrictive-wins* (REVERT > CAUTION > GO) instead of last-wins. Gates run in parallel. New `gate_policy` knobs: `min_gates_for_go`, `metric_required_for_go`, `metric_regression_limit`.
- **Sandbox by default (v1.18):** agent subprocesses no longer inherit the host's full env (DB URLs, cloud creds, tokens). Only PATH/HOME/locale + your `LLM_*` keys + `sandbox_allow_env`. Disabling it logs a visible warning.
- **Real cost control (v1.19):** cost rate is configurable via `assumed_cost_per_mtok` (was hardcoded $3/MTok). `max_daily_cost_usd` — declared since v1.16 but dead — is now **enforced**: per-day tracking, midnight reset, 80% alert, hard stop.
- **Leaner CLI (v1.20+):** `joshua --help` keeps a focused primary surface, now including control, marketplace, eval, memory, Autopilot, permissions, and MCP. Advanced commands still work when called directly; `JOSHUA_SHOW_ALL=1` lists everything.
- **Docs & benchmarks:** README now leads with the release-gate use case. New `benchmarks/` ships a reproducible flaky-tests harness (verifiable without an API key).

See the [complete changelog](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/CHANGELOG.md) for full details.

---

## Contents

- [What is it?](#what-is-it)
- [Supported runners](#supported-runners)
- [Demo](#demo)
- [Current status](#current-status)
- [How it works](#how-it-works)
- [Multi-model technology teams and Specs](#multi-model-technology-teams-and-specs)
- [Distributed control plane](#distributed-control-plane)
- [Signed marketplace](#signed-marketplace)
- [GitHub Autopilot](#github-autopilot)
- [Metrics & Evaluation](#metrics--evaluation)
- [Reproducible evaluations & model routing](#reproducible-evaluations--model-routing)
- [Quick start](#quick-start)
- [Docker](#docker)
- [Design choices](#design-choices)
- [Permissions, isolation & MCP](#permissions-isolation--mcp)
- [Full config reference](#full-config-reference)
- [CLI](#cli)
- [Examples](#examples)
- [Use Cases](#use-cases)
- [Architecture](#architecture)
- [Security](#security)
- [Shell Completion](#shell-completion)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)

## What is it?

joshua-agent is an autonomous release gate for your repository. Each cycle: work agents (dev, bug-hunter, or any custom role) implement the work. A gate agent reviews the output and issues a verdict:

- **GO** → deploy hook runs automatically
- **CAUTION** → sprint continues, findings flagged for review
- **REVERT** → changes rolled back via git, sprint continues on next cycle

On GO the gate auto-deploys your changes; on REVERT it rolls them back via git. Agents share context, extract lessons, and build a wiki that improves future runs. You define the team in a YAML file and walk away.

> *One day, teams will stop babysitting AI. Instead of prompting one agent at a time — copy, paste, check, repeat — they'll define a team in a YAML file and walk away. The agents run in cycles: execute tasks, review each other, deploy or roll back, extract lessons, sleep, repeat. You come back to a log of what happened and (hopefully) better output than yesterday.*
> — @jorgevazquez, April 2026

**Works with any LLM runner.** Claude Code, OpenAI Codex, Aider, OpenCode, or any CLI tool that accepts a prompt. Swap it in the YAML — everything else stays the same. Use different models for different agents: Opus for the gate, Sonnet for work agents, a local model for experiments.

Named after the AI in WarGames that learned the only winning move is to keep playing.

## Supported runners

| Runner | Install | YAML config |
|--------|---------|-------------|
| **Claude Code** | `npm i -g @anthropic-ai/claude-code` | `type: claude` |
| **OpenAI Codex** | `npm i -g @openai/codex` | `type: codex` |
| **Aider** | `pip install aider-chat` | `type: aider` |
| **OpenCode** | `npm i -g opencode-ai` | `type: opencode` |
| **Custom** | any CLI | `type: custom` + `command: 'my-tool --input "{prompt_file}" --dir "{cwd}"'` |

Custom command templates support `{prompt_file}`, `{cwd}`, and `{timeout}`. The prompt is
written to a private temporary file; `{task}` and `{prompt}` are intentionally unsupported
to avoid shell argument-length limits.

Every built-in executable can be overridden with `runner.binary` or
`JOSHUA_<RUNNER>_BINARY` (for example, `JOSHUA_OPENCODE_BINARY=/srv/bin/opencode`). For a
service-account CLI config, set `runner.home`; OpenCode also accepts
`JOSHUA_OPENCODE_HOME`.

## Demo

![joshua-agent demo](https://raw.githubusercontent.com/jorgevazquez-vagojo/joshua-agent/main/assets/demo.gif)

*Real execution: 2 cycles — Cycle 1 GO (deploy), Cycle 2 REVERT (rollback). [asciinema recording](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/assets/demo.cast)*

## Current status

**Stable**

- YAML-defined multi-agent sprints with `work` and `gate` phases
- `GO` / `CAUTION` / `REVERT` verdict loop with snapshot or hillclimb git strategies
- CLI workflow: `joshua run`, `joshua status`, `joshua doctor`, `joshua init`, `joshua examples`, `joshua explain`, `joshua tutorial`, `joshua evolve`, `joshua serve`, and more
- HTTP control plane, process-based runtime, persistence, notifications, and restart recovery
- Safety config with command/path allowlists, protected files, objective metrics, and explicit verdict policy wiring
- Outcome-grounded Learning Engine with immutable episodes, trusted/quarantined memory, provenance, and explainable retrieval
- Persisted GitHub issue/CI Autopilot with plan-only default, isolated worktree, bounded repair, draft PR, and check monitoring
- Per-agent least-privilege manifests, read-only gates, optional strong Docker isolation, and policy-mediated MCP tools
- Deterministic evaluation suites, quarantined shadow comparisons, and fail-closed evidence routing
- Distributed config-reference jobs with idempotency, fenced leases, cancellation, node-only tokens, and no-deploy defaults
- Responsive CSP-locked fleet dashboard and signed skill/template/eval marketplace
- Per-agent/subagent model pinning, model-diverse PR evidence, bounded Specs, and technology skills

**Experimental**

- Unattended live deploys on real production infrastructure
- Exactly-once external side effects across network partitions (not guaranteed)
- Active routing when a local suite does not represent the production task distribution
- Event-driven and on-demand modes that depend on custom task sources and hooks
- Custom runners and hook chains that execute arbitrary shell commands

```
 Work Skills              Gate Skills
+--------------+          +----------+
| Dev          |          |          |
| Bug Hunter   |--------->|   QA     |--> Deploy (or Revert)
| CFO          |          | Review   |
| Any Skill... |          +----------+
+--------------+               |
       ^                       |
       +---- next cycle -------+
```

## How it works

joshua-agent has three core concepts:

- **Skills** — a skill is any professional role you can describe in a prompt. Maintained templates include general engineering plus `software-architect`, `python-dev`, `typescript-dev`, `php-dev`, `salesforce-developer`, `salesforce-marketing-cloud`, `adobe-analytics`, `adobe-experience-platform`, and `adobe-commerce`. You can define any other specialty with `system_prompt:` or a signed marketplace skill.
- **Phases** — agents are either `work` (execute tasks) or `gate` (review and judge). Work agents produce output. Gate agents read that output and return a verdict: `GO` (ship it), `CAUTION` (ship but flag), or `REVERT` (roll back). This separation exists because unsupervised AI output is dangerous. The gate is a circuit breaker.
- **Cycles** — agents don't run once. They cycle. Each cycle picks the next task (round-robin), runs all work agents, feeds the output to gate agents, acts on the verdict, extracts lessons, and sleeps. Then does it again. This is how real teams work — continuous improvement, not heroic one-off efforts.

The runner abstraction means joshua-agent doesn't care what LLM you use. Claude Code, OpenAI Codex, Aider, OpenCode, or any CLI tool. Swap it in the YAML and everything else stays the same.

## Multi-model technology teams and Specs

Assign models at the agent or static-subagent boundary and give every specialist
the same reviewed requirements:

```yaml
specs:
  files: [specs/integration.md, specs/adobe-measurement-plan.md]

agents:
  lead:
    skill: backend-dev
    model: provider/implementation-model
    subagent_synthesis: true
    subagents:
      - {name: php, skill: php-dev, model: provider/php-model}
      - {name: sfmc, skill: salesforce-marketing-cloud, model: provider/platform-model}
  qa:
    skill: qa
    model: other-provider/reviewer-model
```

Model IDs go through the configured runner and never widen permissions. Dynamic
planners cannot choose them. Specs must be explicit project-relative UTF-8
single-link files; traversal, globs, symlinks/hard links, binary data, and byte-budget overflow fail
before any model runs. Their content is hashed, secret-redacted, and delimited
as untrusted requirements data for work agents, subagents, and gates.

See [multi-model teams, technology skills, and Specs](docs/multi-model-skills-specs.md),
the packaged [`multimodel-technology-team.yaml`](examples/multimodel-technology-team.yaml),
and the sequential [`dev-qa-architecture-team.yaml`](examples/dev-qa-architecture-team.yaml).

## Distributed control plane

v2 coordinates reviewed YAML references across machines without copying configs
or secrets into the queue. Jobs are idempotent, label-routed, capacity-aware,
and protected by renewable lease tokens and fencing. Remote deployment is off by
default; deploy-capable jobs are single-attempt and stall instead of retrying
after a lost lease.

```bash
# Server (use generated secrets from a service manager in production)
export JOSHUA_INTERNAL_TOKEN='<admin-token-at-least-16-characters>'
joshua serve

# Node: its configs and runner credentials stay local
export JOSHUA_CONTROL_TOKEN="$JOSHUA_INTERNAL_TOKEN"
joshua control node --config-root ./examples --label environment=dev

# Operator: submit only a safe relative reference
joshua control submit \
  --project demo \
  --config-ref distributed-python.yaml \
  --label environment=dev
```

Use dedicated `node`, `viewer`, `operator`, and `admin` tokens through
`JOSHUA_TOKENS` outside local development. Open `/ui` for the fleet dashboard.
See the [control-plane operations and threat-model guide](docs/control-plane.md).

## Signed marketplace

The v2 marketplace installs skills, complete templates, and eval suites only
after verifying a trusted Ed25519 catalog, signed package manifest, exact file
set, SHA-256 digests, size limits, paths, and the package's domain schema.

```bash
joshua marketplace list
joshua marketplace inspect security-audit
joshua marketplace install security-audit
joshua marketplace installed
```

Installed skills become effective in agent prompt resolution; installed
templates work with `joshua init --template`. Existing activations are preserved
unless force is explicit. See the [marketplace trust, publisher, migration, and
incident-response guide](docs/marketplace.md).

## GitHub Autopilot

Autopilot is the risk-tiered issue/CI-to-PR path for unattended maintenance. Its
default command only reads GitHub and saves a local plan; remote and repository
writes require `--execute`:

```bash
joshua autopilot start joshua.yaml --issue 42
joshua autopilot resume joshua.yaml ap_0123456789abcdef0123456789abcdef --execute

# Or repair a completed failed GitHub Actions run directly
joshua autopilot start joshua.yaml --run-id 123456789 --execute --no-wait

# Merge only if config + risk + acceptance + gate + local/remote checks all allow it
joshua autopilot start joshua.yaml --issue 42 --execute --allow-auto-merge
joshua autopilot evidence joshua.yaml ap_0123456789abcdef0123456789abcdef
```

Every job has an append-only transition history and a hard attempt/diff budget.
The agent works in a dedicated Git worktree; deploys, hooks, task sources, and
agent-owned GitHub operations are disabled. A separate gate emits explicit
acceptance markers; deterministic risk, test, local validation, and GitHub check
evidence controls the decision. Auto-merge is off by default and needs both a
reviewed config opt-in and `--allow-auto-merge` for that run. Sensitive/high-risk
work always stays human-reviewed, and merging uses the exact reviewed head SHA
without admin bypass. See the [complete GitHub PR Quality Autopilot guide](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/autopilot.md).


## Metrics & Evaluation

Each sprint cycle, joshua tracks:

- **Cycle number** — sequential counter since the sprint started
- **Agent durations** — wall-clock seconds each agent took to run
- **Gate verdict** — `GO`, `CAUTION`, or `REVERT` for the cycle
- **Consecutive errors** — how many cycles in a row ended in failure or error
- **Gate findings** — the raw text the gate agent returned, injected into the next cycle

Results are stored in the `.joshua/` directory alongside your project:

```
.joshua/
├── checkpoint.json     Current cycle number, last verdict, error counts
├── results.tsv         One row per cycle — verdict, duration, confidence, description
├── cycles/             Per-cycle Markdown summaries + raw outputs (for replay)
│   ├── cycle-0001.md   Human-readable summary: verdict, cost, gate findings
│   └── cycle-0001.json Raw work-agent outputs (used by `joshua replay`)
├── events/             Structured JSON events per cycle
├── lessons/            One file per cycle — raw lessons extracted from agent output
└── wiki/               Curated knowledge entries built from accumulated lessons
```

To measure progress across cycles, use the status command:

```bash
joshua status .joshua
```

This shows cycle history, verdict distribution, and per-agent timing. Compare cycle 1 vs cycle N to see whether the gate is issuing fewer REVERTs and agents are completing tasks faster.

To evolve agent prompts using accumulated lessons:

```bash
joshua evolve config.yaml
```

`joshua evolve` curates raw lessons into wiki entries and can rewrite agent prompts to incorporate what was learned.

**Honest note:** There is no public benchmark dataset for joshua-agent. What you can track concretely on your own project: GO/REVERT ratio over time, cycle-over-cycle agent duration, and gate finding patterns. Use `joshua status` to build your own baseline.

## Reproducible evaluations & model routing

v1.26 adds project-owned, versioned evaluation suites with deterministic output
assertions and direct verification commands. Every case runs against a bounded
copy of its fixture. Joshua rejects YAML aliases/duplicates, traversal and
symlinks; fingerprints the verification harness before executing checks; and
runs those checks with a minimal credential-free environment. Evidence keeps
scores, hashes, timing and estimated cost—not prompts or raw model responses.

```bash
joshua eval validate evals/core.yaml
joshua eval run joshua.yaml evals/core.yaml --candidate baseline --yes
joshua eval run joshua.yaml evals/core.yaml \
  --candidate baseline --shadow-candidate fast --yes
joshua eval compare joshua.yaml eval_baseline eval_shadow
joshua eval route joshua.yaml --tag work
```

Shadow evidence is excluded from routing until `joshua eval approve <config>
<run> --yes`. The router compares only complete trusted evidence from the same
immutable suite digest. Hard minimum-run/case, confidence, quality-floor and
baseline-regression rules apply before cost or latency can influence selection.
`observe` recommends but executes baseline; `active` is explicit and fails
closed to baseline. Per-agent `model` remains the highest-precedence override.

See the [evaluation and routing guide](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/evaluations-routing.md)
for the suite schema, scoring, CLI, router math, CI workflow, migration path,
privacy design, and threat model.

## Quick start

```bash
pip install joshua-agent
```

## Docker

```bash
# Run a sprint in Docker
docker run --rm -v $(pwd):/workspace \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  ghcr.io/jorgevazquez-vagojo/joshua-agent \
  run sprint.yaml

# Full stack (server + Redis)
docker compose up
```

See `docker-compose.yaml` and `.env.example` for configuration.

**Example 1 — Safe-by-default development sprint.** Start with a wrapper script you control. Keep build, tests, migrations, and health checks inside that script instead of wiring ad hoc shell directly into the first demo.

```yaml
# dev-sprint.yaml
project:
  name: my-app
  path: ~/my-app
  deploy: "./deploy.sh"   # Start here: keep deploy logic behind one script you own

agents:
  dev:
    skill: dev
    tasks:
      - "Review code quality and suggest improvements"
      - "Refactor for maintainability"
  bug-hunter:
    skill: bug-hunter
    tasks:
      - "Scan for uncaught exceptions and error handling gaps"
  qa:
    skill: qa

sprint:
  cycle_sleep: 600
```

Use a wrapper for deploys. It keeps the first sprint reproducible and makes it much easier to add tests, health checks, migrations, or rollback hooks without rewriting the YAML.

**Example 2 — Executive sprint.** No code. No deploy command. Agents analyze documents, audit costs, and check compliance. Same framework, different skills.

```yaml
# executive.yaml
project:
  name: acme-corp
  path: ~/acme-corp-docs

agents:
  cfo:
    skill: cfo
    system_prompt: |
      You are {agent_name}, CFO for {project_name}.
      Analyze financial documents in {project_dir}.
    tasks:
      - "Audit vendor contracts expiring within 90 days"
      - "Analyze monthly burn rate from financial reports"
  compliance:
    skill: compliance
    phase: gate
    verdict_format: true
    system_prompt: |
      You are {agent_name}, Compliance Director.
      Review all analysis for regulatory compliance.

sprint:
  cycle_sleep: 600
  gate_blocking: true
```

```bash
joshua run dev-sprint.yaml    # Software sprint
joshua run executive.yaml     # Business analysis sprint
```

Agents work, gate reviews, act on verdict. Repeat. Any domain, any role.

### What it looks like

```
============================================================
CYCLE 1 — 2026-04-05T03:14:00
============================================================
[cfo] (cfo) Task: Audit vendor contracts expiring within 90 days
[cfo] OK (189.3s, 3841 chars)
[compliance] (compliance) Reviewing cycle 1...
[compliance] OK (94.2s, 1102 chars)
VERDICT: GO
CYCLE 1 COMPLETE — verdict=GO
Sleeping 600s before next cycle...
```

## Design choices

**Skills, not roles.** Every agent is a skill defined in YAML. Built-in skills (`dev`, `qa`, `bug-hunter`, `security`, `perf`, `pm`, `tech-writer`) are convenient starting points — just prompt templates with sensible defaults. But the real power is custom skills: a CFO that audits costs, a legal analyst that reviews contracts, a compliance officer that checks governance, a COO that maps operational bottlenecks. No deploy command needed. No code required. joshua-agent is not a coding tool that happens to support other things. It's a framework for autonomous professional work that happens to be good at code too.

**Two phases: work and gate.** Work agents do the job. Gate agents judge it. This is the single most important design decision in the framework. Without a gate, you're just running unsupervised AI and hoping for the best. The gate is a circuit breaker — `REVERT` means nothing ships. In production, we've seen gate agents catch issues that would have broken deployments, flagged non-compliant analysis, and prevented cascading errors. The two-phase model also means you can scale work agents independently of review capacity.

**Hardened gate consensus.** A single optimistic gate can no longer override a REVERT from another. When you define multiple gate agents, joshua-agent runs them **in parallel** (gates are read-only reviewers — safe to concurrent) and takes the most-restrictive verdict (`REVERT > CAUTION > GO`). `gate_policy.min_gates_for_go` requires N reviewers to agree before a deploy proceeds. Pair with `metric_required_for_go` and `metric_regression_limit` to make the objective metric **binding** — a regression beyond the limit forces REVERT automatically, rather than leaving it to the gate's judgment. Single-gate setups keep their current behavior.

**Continuous cycles, not one-shot.** Most agent frameworks run once and stop. joshua-agent cycles. Each cycle picks the next task from a round-robin queue, so a dev agent with 10 tasks will work through all of them across 10 cycles. The Learning Engine records the final gate, metric, deploy, and rollback outcome as an immutable episode. Only evidence-backed memories are promoted into future prompts.

**Outcome-grounded learning plus wiki curation.** Raw output remains available for wiki synthesis, while operational memory follows a stricter lifecycle: `candidate → trusted / quarantined / rejected`. Recalled memories carry provenance and an explainable score, and `joshua memory evaluate` compares observed outcomes with and without retrieval. See [the Learning Engine guide](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/learning-engine.md).

**LLM-agnostic.** joshua-agent talks to CLI tools, not APIs. Claude Code, OpenAI Codex, Aider, OpenCode, or any custom command that accepts a prompt and returns text. The runner is a one-method interface: `run(prompt, cwd, system_prompt, timeout) -> RunResult`. Swap it in YAML, everything else stays the same. This means you can use different models for different agents — Opus for the gate, Sonnet for work agents, a local model for experiments.

**Gate blocking.** When a gate says `REVERT`, you probably don't want work agents piling more changes on top. `gate_blocking: true` freezes work agents on the next cycle. Only agents marked `run_when_blocked: true` (like bug hunters and security scanners) will run. This prevents compounding failures — the bug hunter fixes what the gate flagged, the gate reviews the fix, and only then does normal work resume.

**Cross-agent context.** Gate findings from the previous cycle get injected into work agents' prompts via `{gate_findings}`. The QA agent tells the dev agent what's wrong. The dev agent fixes it next cycle. They talk through the framework — no manual copy-paste, no context loss between runs.

**Resource-aware scheduling.** Each LLM agent consumes significant memory. Running multiple sprints on the same machine can trigger OOM kills (we learned this the hard way). `min_memory_gb` checks available RAM before each agent run — if memory is low, joshua-agent waits instead of crashing. `agent_stagger` adds a fixed delay between agent executions to let the system breathe. Together, they let you safely run multiple sprints on a single server.

**Objective metrics.** Gate agents are good at qualitative review, but they can't replace a test suite. `project.objective_metric` defines a shell command that returns a number (lower is better). joshua-agent runs it before and after work agents, injects the delta into the gate prompt, and logs both values to `results.tsv`. The gate agent now has hard data alongside its qualitative judgment. Think `pytest --tb=no -q`, a benchmark script, or any command that outputs a number.

**Protected files.** `project.protected_files` lists globs that work agents must not modify. The instruction is injected directly into the task prompt: "DO NOT modify: tests/\*\*, eval.py". This prevents agents from "gaming" the metric by editing the evaluation or test harness — the same pattern Karpathy uses in autoresearch where `prepare.py` is read-only.

**Hillclimb git strategy.** `git_strategy: hillclimb` turns git into a hill-climbing checkpoint. Before each cycle, joshua-agent commits the current state. After work agents run and the gate reviews, a `REVERT` verdict triggers `git reset --hard` to the checkpoint. A `GO` verdict keeps the commit. The result: every surviving commit in git history is a verified improvement. Compare with `snapshot`, which creates branches per cycle — hillclimb is simpler and produces a linear history.

**Three trigger modes.** `sprint.trigger` controls when cycles run. `continuous` (default) runs cycles back-to-back with `cycle_sleep` between them — good for proactive improvement. `event` polls task sources (Jira, GitHub) every `poll_interval` seconds and only runs a cycle when there's real work — no tasks, no LLM calls, no tokens burned. `on_demand` waits for an external trigger via the API (`trigger_cycle()`) — useful for CI/CD integration where a deploy or PR event kicks off a review.

## Permissions, isolation & MCP

v1.25 adds a capability boundary to every agent invocation. Work agents keep a
writable-workspace default; gate agents resolve to a read-only reviewer profile.
You can narrow writable paths, runner tools, optional environment variables,
network intent, and MCP servers per agent. Delegated agents inherit the parent
manifest, and a gate that changes the workspace forces `REVERT` regardless of
its textual verdict.

Optional Docker mode is the strong boundary: digest-pinned image, no Linux
capabilities, `no-new-privileges`, non-root UID/GID, read-only root, resource
limits, controlled network, and read-only Git metadata. Native controls and the
post-run guard remain useful, but they do not contain host filesystem or network
access; use `require_strong_isolation: true` when that distinction matters.

Joshua also implements the current MCP `stdio` lifecycle. Servers need explicit
command consent, server and agent tool allowlists, time/output/call bounds, and a
policy decision. Tool metadata/results are untrusted evidence; unattended
sprints get one read-only tool round, while mutations require a separate
operator-approved CLI call. See the complete [permissions, Docker, and MCP
guide](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/security-isolation-mcp.md).

## Full config reference

```yaml
project:
  name: my-project
  path: ~/my-project                # Any folder — code, docs, reports, data
  deploy: "bash deploy.sh"          # Optional — omit for non-code sprints
  health_url: http://localhost:3000/health  # Optional
  objective_metric: "python scripts/quality_metric.py"  # Command that prints a number (lower = better)
  protected_files:                  # Globs agents must NOT modify
    - "tests/**"
    - "eval.py"

program: |                          # Optional — shared context for ALL agents
  ## Objective
  Reduce p95 latency below 200ms.
  ## Constraints
  - Do NOT modify database schema
  - Only edit files in src/api/

specs:                              # Optional bounded repository requirements
  enabled: true
  files: []                         # Exact paths relative to project.path; no globs/symlinks
  required: true
  max_bytes_per_file: 50000
  max_total_bytes: 200000

runner:
  type: claude                  # claude | codex | aider | opencode | custom
  timeout: 1800                 # Max seconds per agent run
  model: sonnet                 # Model override (optional)
  binary: null                  # Optional executable override (or JOSHUA_<RUNNER>_BINARY)
  home: null                    # Optional HOME override for service-account CLI auth/config
  sandbox: true                 # DEFAULT ON — strip secrets from agent subprocess env
  sandbox_allow_env: []         # Extra env vars to pass through when sandbox=true (e.g. [DATABASE_URL])
  assumed_cost_per_mtok: 3.0    # USD per million tokens for cost estimates (set to match your model)
  max_sprint_cost_usd: 0.0      # 0 = unlimited; hard stop when cumulative spend exceeds this
  max_daily_cost_usd: 0.0       # 0 = unlimited; hard stop when a single day's spend exceeds this
  max_tokens_per_cycle: 50000   # Stop adding work agents above this estimate (0 = off)
  cost_alert_threshold: 0.80    # Warn at 80% of the cost caps above
  isolation:
    mode: native                # native | docker (only Docker is classified strong)
    image: ""                   # Docker: pin image@sha256:<64 lowercase hex chars>
    docker_binary: docker       # Host-side Docker executable/path
    container_binary: ""        # Runner executable inside the image (default: host basename)
    require_digest: true
    pull: never                 # never | missing | always
    read_only_root: true
    memory: 1g
    cpus: 1.0
    pids_limit: 256
    tmpfs_size: 128m

agents:
  dev:
    name: falken                # Custom name (optional)
    skill: dev                  # Built-in or custom skill
    model: provider/model-id    # Optional per-agent override
    assumed_cost_per_mtok: 3.0  # Optional price estimate for this model
    max_changes: 5              # Max changes per cycle
    run_when_blocked: false     # Run even when gate is blocked
    tasks:
      - "Task 1"
      - "Task 2"               # Round-robin through list
    permissions:
      profile: developer        # auto | reviewer | developer | unrestricted
      filesystem: workspace     # none | read | workspace
      network: inherit          # none is enforced only with Docker isolation
      write_paths: ["src/**", "tests/**"]  # Empty = full workspace for developer
      allowed_tools: null       # Runner selectors; null = runner defaults, [] = none
      allowed_env: null         # Narrows runner.sandbox_allow_env for this agent
      mcp_servers: []
      mcp_tools: []             # tool or server.tool; empty = server allowlist
      mcp_max_calls: 0          # 0 disables MCP for this agent; max 10
      allow_mcp_mutations: false
      require_strong_isolation: false
    subagent_mode: static       # static | dynamic; dynamic planners cannot pick models
    subagent_max_parallel: 4
    subagent_synthesis: true
    subagents:
      - name: php-specialist
        skill: php-dev
        model: provider/php-model  # Omit to inherit the parent model
        assumed_cost_per_mtok: 1.0 # Omit to inherit the parent's estimate
        instructions: Review the PHP boundary and add focused tests.

  qa:
    skill: qa                   # Gate skills auto-detect verdict format
    permissions:
      profile: reviewer         # Gate default: read-only; Claude gets Read/Glob/Grep

  cfo:
    skill: cfo
    system_prompt: |            # Any prompt you want
      You are {agent_name}, a CFO reviewing {project_name}.
      Analyze costs, licensing, and resource usage.
    tasks:
      - "Audit third-party dependency costs"

sprint:
  trigger: continuous           # continuous | event | on_demand
  poll_interval: 300            # Seconds between polls (event/on_demand modes)
  cycle_sleep: 300              # Seconds between cycles
  max_cycles: 0                 # 0 = infinite
  max_hours: 96                 # 0 = infinite
  digest_every: 12              # Summary report every N cycles
  retries: 2                    # Retry failed agent runs
  revert_sleep: 600             # Longer sleep after REVERT
  max_consecutive_errors: 5     # Stop after N errors in a row
  gate_blocking: true           # REVERT blocks work agents
  cross_agent_context: true     # Gate findings -> work agents
  health_check: true            # Check health_url each cycle
  recovery_deploy: "bash rollback.sh"
  git_strategy: hillclimb       # none | snapshot | hillclimb
  agent_stagger: 30             # Seconds to wait between agent runs
  min_memory_gb: 4              # Wait for free RAM before each agent

gate_policy:                     # Gate hardening — how multiple gates combine
  parallel: true                 # Run gate agents concurrently (read-only, safe)
  min_gates_for_go: 1            # Min gates that must vote GO to deploy (>=1)
  metric_required_for_go: false  # GO -> CAUTION if no objective_metric configured
  metric_regression_limit: 0.0   # GO -> REVERT if (metric_after - metric_before) > limit

evaluation:
  state_dir: .joshua/evaluations # Relative paths resolve under project.path
  candidates:
    baseline: {}                 # Inherit the complete runner configuration
    fast:
      model: provider-fast-model
      assumed_cost_per_mtok: 1.0
      tags: [work]
      enabled: true
      routable: true
    benchmark-only:
      type: claude               # Cross-runner measurement is allowed...
      model: provider-model
      routable: false            # ...but never live-routed in this sprint
  routing:
    mode: "off"                  # off | observe | active (quote YAML "off")
    baseline: baseline
    suite: release-gate-core
    suite_digest: ""             # Optional immutable SHA-256 suite pin
    min_runs: 2
    min_cases: 10
    quality_floor: 0.80
    max_score_regression: 0.02
    confidence_z: 1.96
    cost_weight: 0.05
    latency_weight: 0.02
  allowed_tools: [Read, Glob, Grep, Edit, Write]
  max_cases_per_run: 100
  max_eval_cost_usd: 5.0         # Worst-case output estimate per candidate run

mcp:
  enabled: false                 # Opt-in; no MCP process starts while false
  protocol_version: "2025-11-25"
  servers:
    repository:
      transport: stdio
      command: [repo-mcp, --stdio] # Exact argv; shell/inline code is rejected
      consent: false               # Review exact command/image/env, then set true
      allowed_tools: [search, read_symbol]  # Empty exposes no tools
      mutating_tools: []           # Subset of allowed_tools; policy-gated
      allowed_agents: [dev]
      env: []                      # Environment variable names, never values
      timeout_seconds: 30
      max_output_chars: 12000
      isolation: process           # trusted process | docker
      network: inherit             # network:none requires Docker
      image: ""                     # Docker MCP image@sha256:<digest>
      require_digest: true

preflight:
  min_disk_gb: 5                # Check disk before each cycle
  min_memory_gb: 4              # Check RAM before each cycle
  memory_wait_timeout: 120      # Seconds to wait if memory is low
  docker_cleanup: true          # Auto-clean Docker on low disk

notifications:
  type: telegram                # telegram | slack | webhook | none
  token: ${TELEGRAM_TOKEN}
  chat_id: ${TELEGRAM_CHAT_ID}

tracker:
  type: jira                    # jira | github | filesystem | none
  base_url: https://x.atlassian.net
  project_key: PROJ

memory:
  enabled: true
  state_dir: .joshua
  learning_engine: true          # Outcome-grounded episodic memory
  lessons_per_cycle: 3           # Max candidate memories extracted per cycle
  promotion_threshold: 2         # GO evidence required for trusted patterns
  failure_promotion_threshold: 1 # REVERT evidence required for anti-patterns
  max_memories_per_prompt: 3     # Trusted memories injected per agent task
  max_memory_prompt_chars: 2000  # Prompt budget for recalled experience
  retrieval_min_score: 0.20      # Minimum relevance/evidence score
  max_lesson_age_cycles: 50      # Legacy-memory compatibility

autopilot:
  base_branch: main
  remote: origin
  branch_prefix: joshua/autopilot
  max_repair_attempts: 2         # Bounded to 1..5
  max_files_changed: 20
  max_changed_lines: 1200        # Additions + deletions
  protected_paths: []            # Extends project.protected_files + secret defaults
  allowed_paths: []              # Empty = any non-protected repository path
  allow_binary_files: false
  draft_pr: true                 # Eligible drafts become ready only at merge time
  wait_for_checks_seconds: 900
  poll_interval_seconds: 15
  validation_commands:           # Direct commands only; no pipes/redirections/bash -c
    - python -m pytest -q
    - ruff check .
  validation_timeout_seconds: 1200
  repair_agents: []              # Empty = all work-phase agents
  require_gate: true
  quality:
    enabled: true
    auto_merge: false             # Also needs --allow-auto-merge on the exact run
    auto_merge_max_risk: low      # High/critical always require a human
    merge_method: squash
    require_source_criteria: true
    require_regression_test: true
    require_local_validation: true
    require_github_checks: true
    require_model_diversity: true # Reviewer IDs disjoint from all implementation IDs
    required_checks: []           # Exact names; [] still requires reported passes
    sensitive_paths: []           # Extends auth/migration/infra/payment defaults
```

### Dynamic task sources

Agents can pull tasks from external systems instead of a static YAML list:

```yaml
agents:
  dev:
    skill: dev
    task_source: github           # or: jira | gate
    task_source_config:
      repo: acme/backend          # owner/repo
      token: ${GITHUB_TOKEN}      # optional — for private repos / higher rate limit
      labels: "bug,help wanted"   # optional label filter
      max_results: 20             # issues to consider per cycle

  qa:
    skill: qa
    task_source: jira
    task_source_config:
      base_url: https://company.atlassian.net
      user: ${JIRA_USER}
      token: ${JIRA_TOKEN}
      jql: "project = PROJ AND type = Bug AND resolution = Unresolved"

  fixer:
    skill: dev
    task_source: gate             # Use top issue from last gate findings as task
```

| Source | Description |
|--------|-------------|
| `github` | Open issues from a GitHub repo (filters out PRs, round-robin by cycle) |
| `jira` | Issues from a Jira JQL query (requires HTTPS) |
| `gate` | Generates task from last gate verdict's top finding (REVERT/CAUTION → resolves issues) |

Template variables available in agent prompts: `{agent_name}`, `{skill}`, `{project_name}`, `{project_dir}`, `{deploy_command}` (from `project.deploy`), `{program}` (from top-level `program:`), `{specs}` (bounded loaded Specs), `{memory}`, `{wiki}`, `{gate_findings}`, `{max_changes}`.

Each cycle appends one row to `.joshua/results.tsv` — a greppable, diffable log that doesn't need the CLI:

```
cycle  verdict  duration_s  agents          confidence  metric_before  metric_after  description
1      GO       284.1       dev,bug-hunter  0.94        12.3           8.1           Fixed SQL injection...
2      REVERT   312.0       dev,qa          0.97        8.1            15.2          Auth middleware broke...
```

## CLI

`joshua --help` shows only **primary commands** (run, status, serve, compare, trace, init, doctor, …). Advanced commands (promote, rollback, fleet, schedule, secure, verify-audit, replay, export, diff, distill, evolve, audit, …) are hidden from the listing but still work when called directly. Set `JOSHUA_SHOW_ALL=1` to list them all.

### Onboarding

```bash
joshua tutorial                         # Simulated sprint walkthrough — no API key needed
joshua getting-started                  # Guided setup walkthrough
joshua examples                         # List all built-in example configs with descriptions
joshua examples python-api              # Copy a template to current directory
joshua examples python-api --show       # Print template contents
joshua init                             # Interactive setup wizard
joshua init --template minimal          # Start from a built-in template
joshua schema > joshua-schema.json      # Export JSON Schema for IDE YAML autocomplete
joshua explain config.yaml              # Human-readable sprint plan + cost estimate
joshua explain-cycle config.yaml -c 3   # Explain a past gate verdict
joshua doctor config.yaml               # Pre-flight checks (Python, runner, git, path, creds)
```

### Evaluations, shadow mode, and routing

```bash
joshua eval validate evals/core.yaml
joshua eval run config.yaml evals/core.yaml --candidate baseline --yes
joshua eval run config.yaml evals/core.yaml \
  --candidate baseline --shadow-candidate fast --yes
joshua eval report config.yaml
joshua eval show config.yaml eval_abcd1234
joshua eval compare config.yaml eval_baseline eval_shadow
joshua eval approve config.yaml eval_shadow --yes
joshua eval route config.yaml --tag work --json
```

Trusted failures return a nonzero exit code for CI; shadow failures never affect
the exit status or sprint decisions. Raw prompts and model output are not stored.
Read the [full evaluation and routing guide](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/evaluations-routing.md).

### Distributed control plane

```bash
joshua control status --server https://control.example.net
joshua control node --server https://control.example.net --config-root /etc/joshua/configs
joshua control submit --server https://control.example.net \
  --project api --config-ref teams/api.yaml --label region=eu
joshua control cancel job-0123456789abcdef
```

Set `JOSHUA_CONTROL_TOKEN`; tokens are deliberately unavailable as CLI options.
Node-only credentials cannot invoke operator routes. See the [complete control
plane guide](docs/control-plane.md).

### Signed marketplace

```bash
joshua marketplace list
joshua marketplace inspect security-audit
joshua marketplace install security-audit
joshua marketplace installed
joshua marketplace verify skill/security-audit@2.0.0
```

Catalog and package signatures, hashes, exact paths, size bounds, and the
skill/template/eval schema are verified before any write. See the [marketplace
trust and publishing guide](docs/marketplace.md).

### Permissions and MCP

```bash
joshua permissions show config.yaml              # Resolve profiles; starts nothing
joshua permissions show config.yaml --agent qa --json
joshua permissions audit config.yaml --limit 100 # Permission + MCP JSONL audit
joshua mcp list config.yaml                       # Review config; starts nothing
joshua mcp inspect config.yaml repository --yes  # Start and inspect live allowlist
joshua mcp call config.yaml repository search \
  --agent dev --arguments '{"query":"auth"}' --yes
```

`mcp inspect` and `mcp call` require immediate `--yes` in addition to the
server's persisted `consent: true`. Mutations also require
`--approve-mutation`, agent permission, and a non-`DENY` policy result. See the
[security and MCP guide](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/security-isolation-mcp.md).

### Running

```bash
joshua run config.yaml                  # Run a sprint
joshua run config.yaml -n 10            # Max 10 cycles
joshua run config.yaml -H 96            # Max 96 hours
joshua run config.yaml --dry-run        # Validate config only
joshua run config.yaml --agents dev,qa  # Run only specific agents
```

### Monitoring

```bash
joshua status .joshua                   # Status dashboard
joshua watch .                          # Live-refresh dashboard (Ctrl+C to stop)
joshua status .joshua --json            # Machine-readable JSON (for CI: | jq .checkpoint.cycle)
joshua logs .joshua                     # Print last 50 log lines
joshua logs .joshua --follow            # Live tail (like tail -f)
```

### Trace Viewer

Every cycle generates `.joshua/traces/cycle-N.json` — a structured tree of the full execution: orchestrator → agents → tool calls → gate → verdict.

```bash
joshua trace show .                       # ASCII tree of latest cycle
joshua trace show . --cycle 3             # Specific cycle
joshua trace show . --format json         # Raw JSON (pipe to jq)
joshua trace show . --format flat         # Flat indented list
joshua trace list .                       # Table: cycle | verdict | duration | agents | tokens
```

The HTTP server also exposes:
- `GET /sprints/{id}/trace` — trace JSON for latest (or `?cycle=N`) cycle
- `GET /sprints/{id}/trace/list` — list of all available cycles
- `GET /ui/trace/{sprint_id}/{cycle}` — interactive D3.js tree viewer in browser

### Analysis & export

```bash
joshua replay config.yaml --cycle 7    # Re-run gate on saved cycle output (no work agents)
joshua export .joshua                   # Sprint report as Markdown (stdout)
joshua export .joshua --format json     # Sprint report as JSON
joshua export .joshua --cycles 5        # Last 5 cycles only
joshua diff .joshua --cycle 3 --cycle 7 # Compare two cycles side by side (verdict, confidence, findings diff)
joshua diff .joshua                     # Compare last two cycles
joshua distill .joshua1 .joshua2        # Consolidate lessons across multiple sprints
```

### Environment comparison

```bash
joshua compare dev.yaml pre.yaml pro.yaml           # Compare existing results side by side
joshua compare dev.yaml pre.yaml pro.yaml --run      # Run one QA cycle first, then compare
joshua compare dev.yaml pre.yaml pro.yaml --run --parallel  # Run all envs concurrently
joshua compare dev.yaml pre.yaml pro.yaml -f markdown       # GFM table (for reports, Jira, etc.)
joshua compare dev.yaml pre.yaml pro.yaml -f json           # JSON output (for CI/dashboards)
joshua compare dev.yaml pre.yaml pro.yaml -o report.md -f markdown  # Save to file
joshua compare dev.yaml pre.yaml pro.yaml -f markdown -e client@example.com  # Email report
```

`compare` reads `.joshua/checkpoint.json` and `.joshua/results.tsv` from each config's state directory and renders a side-by-side verdict matrix. The first environment is the **baseline** — regressions against it are flagged automatically.

**Example output (`--format table`):**

```
Environment comparison — 2026-04-08 14:55
──────────────────────────────────────────────────────────────────────────────
Environment    Verdict          Cycle   Conf  Dur(s)  vs base   Top finding
──────────────────────────────────────────────────────────────────────────────
dev            ✓  GO              12   0.92   142.3  =          Auth fix deployed OK
pre            ⚠  CAUTION          9   0.71   189.1  ▼ worse    DB pool size warning
pro            ✗  REVERT           7   0.97     —    ▼ worse    SQL injection in /search
──────────────────────────────────────────────────────────────────────────────
→ REVERT in one or more environments — block promotion
```

Column reference:

| Column | Description |
|--------|-------------|
| `Environment` | Config filename (without `.yaml`) |
| `Verdict` | Last gate verdict from `checkpoint.json` |
| `Cycle` | Cycle number when verdict was issued |
| `Conf` | Gate confidence score (0–1) |
| `Dur(s)` | Average cycle duration in seconds |
| `vs base` | Regression vs first environment (`=` same · `▲ better` · `▼ worse`) |
| `Top finding` | First line of last gate findings |

Summary line logic:

| Condition | Summary |
|-----------|---------|
| All envs GO | `→ All environments GO — ready to promote` |
| Any REVERT | `→ REVERT in one or more environments — block promotion` |
| Any CAUTION, no REVERT | `→ CAUTION in one or more environments — review before promoting` |

### Release flow

```bash
joshua promote dev.yaml pre.yaml pro.yaml           # Promote all envs in sequence if all GO
joshua promote dev.yaml pre.yaml pro.yaml --dry-run # Show what would be deployed
joshua promote dev.yaml pre.yaml pro.yaml --force   # Skip gate verification between envs
joshua rollback dev.yaml                            # Git rollback to last snapshot SHA
joshua rollback dev.yaml --to HEAD~1                # Rollback to specific git ref
joshua rollback dev.yaml --dry-run                  # Show before/after SHA without rolling back
```

### Learning and memory

```bash
joshua memory status .                              # Episodes, rewards and memory states
joshua memory history . --limit 20                  # Immutable outcome history
joshua memory search "authentication token" .       # Explainable trusted retrieval
joshua memory explain mem_abcd1234 .                # Provenance and usage history
joshua memory forget mem_abcd1234 .                 # Reject, preserving the audit trail
joshua memory evaluate .                            # Compare outcomes with/without memory
```

See [Learning Engine](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/learning-engine.md) for promotion, quarantine, scoring,
security, configuration, and HTTP endpoints.

### GitHub issue and CI repair

```bash
joshua autopilot start config.yaml --issue 42               # Persist plan only
joshua autopilot start config.yaml --run-id 123456 --execute # Repair failed run
joshua autopilot status config.yaml                          # List jobs
joshua autopilot status config.yaml ap_abcd... --json        # Full audit history
joshua autopilot evidence config.yaml ap_abcd... --json      # Risk + acceptance + checks
joshua autopilot resume config.yaml ap_abcd... --execute     # Continue plan/checks
joshua autopilot resume config.yaml ap_abcd... --execute --allow-auto-merge
joshua autopilot cancel config.yaml ap_abcd...               # Retain branch/PR/evidence
```

The `gh` CLI supplies authentication. `--execute` is always explicit; without
it, start/resume perform no branch, agent, push, or PR mutation. Merge needs a
second per-run grant and still obeys risk/evidence policy plus GitHub protection.
See [GitHub PR Quality Autopilot](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/autopilot.md)
for acceptance contracts, risk scoring, evidence, state transitions, recovery,
migration, and threat model.

### Skills

```bash
joshua skill list                       # List all built-in skills with descriptions
joshua skill new                        # Interactive wizard to create a custom skill
joshua skill install security-audit     # Compatibility alias for signed marketplace install
```

Custom skills are saved to `~/.joshua/skills/<name>.yaml` and available in any config with `skill: <name>`.
The built-in catalog includes PHP, Salesforce/Marketing Cloud, Adobe Analytics,
AEP, and Adobe Commerce profiles; these are engineering prompts, not platform
credentials or certifications.

### Automation

```bash
joshua fleet fleet.yaml                 # Run multiple projects from a YAML list
joshua fleet fleet.yaml --dry-run       # Preview without running
joshua schedule config.yaml --interval 3600         # Run QA every 1 hour
joshua schedule config.yaml --cron "0 8 * * 1-5"   # Print crontab command for 8am Mon-Fri
joshua schedule config.yaml --dry-run               # Show next 5 run times
joshua watch-git config.yaml --branch main          # Trigger a sprint for each new commit
joshua serve                            # Start HTTP control plane (default: 127.0.0.1:8100)
joshua serve --cert-file c.pem --key-file k.pem  # HTTPS
joshua evolve config.yaml              # Run evolution + wiki maintenance
joshua completion bash >> ~/.bashrc     # Shell completion (bash/zsh/fish)
```

> **Deploy safety**: `project.deploy` runs as a shell command with your user's permissions. Shell metacharacters (`;`, `|`, `` ` ``, `$(`) are rejected by config validation. Use dry-run mode (`joshua run config.yaml --dry-run`) to validate before running. Never use untrusted YAML configs.

## Examples

See [`examples/`](https://github.com/jorgevazquez-vagojo/joshua-agent/tree/main/examples) for ready-to-use configs:

**Business & governance:**
- [`executive-team.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/executive-team.yaml) — CFO + COO + Compliance Director
- [`legal-review.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/legal-review.yaml) — Legal Analyst + Risk Assessor + General Counsel

**Software development:**
- [`minimal.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/minimal.yaml) — 3 agents, zero config
- [`full-team.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/full-team.yaml) — Dev, Bug Hunter, Security, Perf, PM, QA
- [`wordpress.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/wordpress.yaml) — WordPress: WCAG, SEO, PHP audits
- [`nextjs.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/nextjs.yaml) — Next.js: TypeScript, React, API audits
- [`python-api.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/python-api.yaml) — FastAPI/Django: testing, security, DB audits
- [`autopilot.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/autopilot.yaml) — bounded GitHub issue / failed-CI repair into a draft PR
- [`secure-mcp.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/secure-mcp.yaml) — digest-pinned Docker permissions plus a consent-first MCP template
- [`evaluation.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/evaluation.yaml) — baseline/challenger routing policy with a deterministic fixture suite under `examples/evals/`
- [`multimodel-technology-team.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/multimodel-technology-team.yaml) — model-diverse PHP, Salesforce, Marketing Cloud, Adobe, implementation, test, and gate team with Specs
- [`dev-qa-architecture-team.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/dev-qa-architecture-team.yaml) — sequential Specs → Architecture → DEV → QA automation workflow with independent QA and architecture gates

## Use Cases

Four ready-to-run packs for common scenarios:

### Pack 1: Continuous Release Gate

Agents: `dev` (implement feature or fix), `qa` (quality gate with GO/CAUTION/REVERT).
Runs your CI-equivalent autonomously — auto-deploys on GO, reverts on REVERT, sleeps and repeats. Drop-in replacement for a human code reviewer on low-risk branches. Example: [`examples/minimal.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/minimal.yaml).

### Pack 2: Legacy Modernization

Agents: `dev` (modernize code), `bug-hunter` (find regressions), `qa` (gate review).
Each cycle improves one area of a legacy codebase. The gate blocks the next cycle if tests break or regressions appear, so changes accumulate safely. Example: [`examples/python-api.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/python-api.yaml).

### Pack 3: Client QA Across Environments (DEV / PRE / PRO)

Ideal for agencies running QA as a service on behalf of a client. Each environment gets its own config file. Runs are point-in-time (one review cycle, not continuous) triggered by your CI pipeline or manually before a release.

**Setup — one config per environment:**

```yaml
# dev.yaml
project:
  name: client-app-dev
  path: ~/client-app
  health_url: https://dev.client.com/health
  objective_metric: "python scripts/smoke_metric.py"

agents:
  researcher:
    skill: dev
    system_prompt: |
      You are a QA analyst reviewing the DEV environment of {project_name}.
      Check for functional regressions, broken flows, and performance issues.
    tasks:
      - "Audit all critical user flows and flag any regressions"
  qa:
    skill: qa
    phase: gate
    verdict_format: true

sprint:
  trigger: on_demand       # Only runs when explicitly triggered — no idle cycles
  max_cycles: 1            # One review pass, then stop
  gate_blocking: true
```

Duplicate `dev.yaml` → `pre.yaml` → `pro.yaml`, adjusting `project.name`, `health_url`, and `path` for each environment.

**Run QA across all three environments:**

```bash
# Option A — compare existing results (no new LLM calls)
joshua compare dev.yaml pre.yaml pro.yaml

# Option B — run a fresh QA cycle on each, then compare
joshua compare dev.yaml pre.yaml pro.yaml --run

# Option C — run all three in parallel (faster), then compare
joshua compare dev.yaml pre.yaml pro.yaml --run --parallel

# Export results as a Markdown report for the client
joshua compare dev.yaml pre.yaml pro.yaml -f markdown -o qa-report-$(date +%F).md
```

**Example output:**

```
Environment comparison — 2026-04-08 14:55
──────────────────────────────────────────────────────────────────────────────
Environment    Verdict          Cycle   Conf  Dur(s)  vs base   Top finding
──────────────────────────────────────────────────────────────────────────────
dev            ✓  GO              1    0.94   138.2  =          All smoke tests pass
pre            ⚠  CAUTION         1    0.78   201.4  ▼ worse    Slow checkout (3.2s avg)
pro            ✓  GO              1    0.91   144.0  =          No regressions found
──────────────────────────────────────────────────────────────────────────────
→ CAUTION in one or more environments — review before promoting
```

**Delivering results to the client:**

The Markdown report (`-f markdown -o report.md`) is ready to paste into Confluence, Jira, Notion, or send by email. For automated delivery, pipe the output through your existing notification system or attach the file in CI.

**Scheduling (SLA):**

Add to your CI pipeline to run QA automatically before each release:

```yaml
# .github/workflows/qa.yml
- name: Environment QA comparison
  run: |
    pip install joshua-agent
    joshua compare dev.yaml pre.yaml pro.yaml --run --parallel \
      -f markdown -o qa-report.md
- name: Upload QA report
  uses: actions/upload-artifact@v4
  with:
    name: qa-report
    path: qa-report.md
```

Or use the official Joshua GitHub Action for a zero-config sprint integration:

```yaml
# .github/workflows/qa.yml
- uses: jorgevazquez-vagojo/joshua-agent@v2.1.0
  with:
    config: sprint.yaml
    anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
```

Or use `joshua fleet` with `parallel: true` if you want full sprint logs per environment in addition to the comparison summary.

> **Note on functional testing:** joshua-agent's QA agents are LLM-based reviewers — they analyze code, logs, and output. For browser-level functional testing (Playwright, Cypress, Selenium), run a reviewed wrapper script as `project.objective_metric` and let the gate interpret its numeric result. Shell pipelines are intentionally rejected in config; use, for example, `objective_metric: "python scripts/playwright_metric.py"`.

### Pack 4: Document & Compliance Review

Agents: `analyst` (review documents), `legal` (compliance check), `executive` (summary + gate).
Multi-agent review cycle for contracts, policies, or technical specs. No deploy command needed — the gate verdict determines whether the document passes or requires revision. Example: [`examples/legal-review.yaml`](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/examples/legal-review.yaml).

## Architecture

```
joshua/
├── cli.py              CLI entry point
├── commands/
│   ├── autopilot.py    Autopilot plan/execute/evidence/status/resume commands
│   ├── control.py      Distributed submit/status/node/cancel commands
│   ├── evals.py        Evaluation, shadow, comparison and routing commands
│   ├── group.py        Primary/advanced command visibility policy
│   ├── memory.py       Learning Engine CLI (status/search/history/evaluate)
│   ├── marketplace.py  Signed package discovery/install/verification
│   ├── security_controls.py Permission and MCP inspection/call commands
│   ├── ui.py           Shared spinner and friendly errors
│   └── watch.py        Dashboard + git-triggered watch commands
├── autopilot/
│   ├── engine.py       Persistent bounded repair state machine
│   ├── github.py       Validated checks, PR state and exact-head merge adapter
│   ├── models.py       Atomic job state and transition history
│   ├── quality.py      Risk, acceptance, evidence and merge decision policy
│   └── workspace.py    Dedicated worktrees and change-policy enforcement
├── config.py           YAML loader + ${ENV} interpolation
├── sprint.py           The loop (work → gate → deploy/revert → learn → sleep → repeat)
├── agents.py           Skill definitions + prompt templates
├── security/
│   ├── isolation.py    Hardened Docker invocation builder
│   └── permissions.py Per-agent manifests, audit and workspace/Git guards
├── mcp/
│   ├── client.py       Bounded MCP stdio lifecycle and tools client
│   └── broker.py       Consent, dual allowlists, policy and untrusted evidence
├── evals/
│   ├── models.py       Strict suite, candidate and routing schemas
│   ├── suite.py        Canonical digest and bounded fixture copies
│   ├── engine.py       Deterministic assertions/check execution
│   ├── store.py        Private metrics-only SQLite evidence
│   └── router.py       Confidence/quality/cost/latency selection
├── control_plane/
│   ├── models.py       Strict node/job/lease/result contracts
│   ├── store.py        Durable idempotent queue, leases, fencing and events
│   ├── node.py         Reference config-local fleet node and HTTP client
│   ├── api.py          Versioned role-gated FastAPI router
│   └── dashboard.py    CSP-compatible dependency-free dashboard assets
├── marketplace/
│   ├── models.py       Strict catalog, manifest and skill schemas
│   ├── security.py     Ed25519, hashing, paths, ZIP/YAML/JSON boundaries
│   ├── catalog.py      Discovery, atomic installation and runtime activation
│   └── catalog/        Signed built-in trust root and packages
├── runners/
│   ├── base.py         LLMRunner interface
│   ├── registry.py     Runner catalog, binary resolution, factory
│   ├── claude.py       Claude Code
│   ├── codex.py        OpenAI Codex
│   ├── aider.py        Aider
│   ├── opencode.py     OpenCode
│   └── custom.py       Any CLI tool
├── memory/
│   ├── engine.py       Outcome episodes, rewards, promotion and retrieval
│   ├── lessons.py      Extract lessons from each cycle
│   ├── wiki.py         Karpa pattern knowledge base
│   └── evolve.py       Daily evolution + lint
├── integrations/
│   ├── git.py          Snapshot, merge, revert
│   ├── notifications.py Telegram, Slack, webhook
│   └── trackers.py     Jira, GitHub Issues, filesystem
└── utils/
    ├── health.py       HTTP health checks
    ├── preflight.py    Disk, memory, Docker cleanup
    └── status.py       Dashboard
```

## Security

Joshua combines configuration scanning, signed evidence, least privilege,
optional containment, and bounded automation:

- **`joshua secure <config>`** — scan your YAML for hardcoded tokens, passwords, and API keys before committing. Detects Slack tokens, GitHub PATs, and generic secrets. Use `--fix` to get suggested `export` commands.
- **Signed verdicts** — set `JOSHUA_SIGNING_KEY` to enable HMAC-SHA256 signatures on every row in `results.tsv`. Verify integrity with `joshua verify-audit <project_dir>`.
- **Rate limiting** — server enforces 30 req/60s per token (configurable via `JOSHUA_RATE_LIMIT`). Explicit `check_rate_limit()` function available for per-endpoint use.
- **Agent manifests** — work and gate agents receive phase-aware filesystem, network, tool, environment, and MCP capabilities. Native runs are checked for durable workspace and Git-control changes; a violating gate forces REVERT.
- **Strong Docker mode** — digest pinning, dropped capabilities, non-root execution, read-only root/Git metadata, resource limits, and network control. `runner.sandbox` alone only filters environment variables and is not an OS sandbox.
- **MCP broker** — exact-command consent, stdio-only transport, dual tool allowlists, policy-gated mutations, bounded traffic, untrusted-data delimiters, and a private secret-redacted audit. Process-mode MCP is trusted host code; use Docker for untrusted servers.
- **Autopilot boundary** — GitHub source text is delimited as untrusted data; repository/ref/job identifiers are validated; work happens in a dedicated worktree; nested protected files, external symlinks, hard links, special/oversized files, binaries, and diff-budget excesses stop publication. Deterministic risk/evidence keeps sensitive/high-risk work human-reviewed. Eligible low-risk merge needs config plus per-run consent, every reported check passing, immediate PR-state revalidation, exact-head fencing, and normal GitHub protection; Joshua never uses admin bypass or delegates deploy/merge to agents.
- **Specs/model boundary** — Specs use exact relative paths, strict UTF-8 and byte budgets, no symlinks/binary data, secret redaction, hashes, and untrusted-data delimiters. Model overrides cannot change runner type or capabilities; declared model diversity reduces correlated review risk but is not provider attestation.
- **Evaluation boundary** — suites are strict and hashed; fixtures are bounded disposable copies; harness changes block checks; verification gets a minimal environment; raw prompts/responses are not persisted; shadow evidence is quarantined; routing is digest-matched and fails closed to baseline. Generated code still needs a container/VM when it is not trusted.
- **Fleet boundary** — the queue stores config references rather than configs/secrets, uses idempotency and hashed fenced leases, accepts metrics-only completion, separates node/viewer/operator/admin tokens, and forces remote no-deploy unless explicitly granted. Fencing cannot guarantee exactly-once third-party side effects.
- **Marketplace boundary** — trusted Ed25519 catalog and package signatures pin every file by path, size, and SHA-256. Links, traversal, duplicate/aliased YAML, unexpected members, private remote targets, and unsafe activation replacement fail closed. Signed content is authenticated, not automatically safe to execute.

```bash
joshua secure my-project.yaml
joshua secure my-project.yaml --fix
JOSHUA_SIGNING_KEY=mysecret joshua run my-project.yaml
joshua verify-audit .joshua/
```

## Shell Completion

Enable tab completion for your shell:

```bash
# zsh
echo 'eval "$(_JOSHUA_COMPLETE=zsh_source joshua)"' >> ~/.zshrc

# bash
echo 'eval "$(_JOSHUA_COMPLETE=bash_source joshua)"' >> ~/.bashrc

# fish
echo '_JOSHUA_COMPLETE=fish_source joshua | source' >> ~/.config/fish/config.fish

# Or use the helper command:
joshua completion zsh
```

## Documentation

| Doc | Description |
|---|---|
| [Release history](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/releases.md) | Complete immutable release history from v1.0.0 onward |
| [v2 control plane](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/control-plane.md) | Fleet topology, roles, leases, API, dashboard, recovery, migration and threat model |
| [Signed marketplace](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/marketplace.md) | Trust chain, package/catalog schemas, publisher keys, operations, migration and limits |
| [Learning Engine](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/learning-engine.md) | Outcome rewards, memory lifecycle, retrieval, CLI and HTTP API |
| [GitHub PR Quality Autopilot](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/autopilot.md) | Acceptance criteria, risk tiers, evidence, exact-head merge policy, recovery and threat model |
| [Multi-model teams, skills and Specs](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/multi-model-skills-specs.md) | Model roles, delegated fan-out, technology catalog, Spec loading, limits and PR evidence |
| [Permissions, Docker and MCP](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/security-isolation-mcp.md) | Capability profiles, guarantees, config, MCP lifecycle, audit, migration and threat model |
| [Evaluations and routing](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/evaluations-routing.md) | Suite format, shadow lifecycle, scoring, evidence router, CI, privacy, migration and threat model |
| [E-commerce QA](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/ecommerce-qa.md) | E-commerce QA skills: researcher, magento-hunter, mobile-tester, ecommerce-qa |
| [Primor setup](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/docs/primor-setup.md) | Production setup guide for running QA sprints against primor.eu |

## Contributing

Contributions are welcome — open an [issue](https://github.com/jorgevazquez-vagojo/joshua-agent/issues) or a [pull request](https://github.com/jorgevazquez-vagojo/joshua-agent/pulls). CI runs on every push to keep `main` green.

Areas where help is needed:

- **Runners**: Cursor, Windsurf, VS Code Copilot
- **Trackers**: Notion, Trello (Linear and Jira/GitHub already supported)
- **Notifiers**: PagerDuty (Telegram, Slack, Discord, email, webhook already supported)
- **Skills**: share your custom skill templates

## License

MIT. See [LICENSE](https://github.com/jorgevazquez-vagojo/joshua-agent/blob/main/LICENSE).

---

Built by [Jorge Vazquez](https://github.com/jorgevazquez). The only winning move is to keep playing.
