Skip to content

Glossary

Junior has exactly two core concepts — Runbook and Harness. Everything else (settings, models, the registry) is plumbing around them: field-level reference in Configuration, internals in Architecture, the why in Philosophy.

One task domain — the whole vertical for a kind of task: collect context → render it → run the harness → publish the result. It owns its context schema and result schema and implements the domain logic. Defined as an ABC, Runbook[Context, Result], in src/junior/runbook/base.py.

A runbook is selected explicitly (--runbook NAME, config runbook:, or env RUNBOOK; required — there is no implicit default). It can come from any of four sources: a built-in, a pip-installed plugin, a module:ClassName import path, or a repo-local file in .junior/runbooks/ (opt-in — Python or a plain YAML manifest); see Adding runbooks & harnesses.

The contract a runbook implements:

MethodRole
collect(settings) → ContextGather domain context (a git diff, an API call, a shell command)
render(context, settings, *, file_access) → strBuild the user message the LLM sees
system_prompt(settings) → strRole + rules layer (default empty)
publish(settings, result, usage, *, errors)Custom publish — runs only with --publish (post / pretty render / run a script)
render_output(result) → strDefault output (no --publish): the raw result, unformatted (default JSON)
validate(settings, *, publish_enabled) → list[str]Runbook-specific config checks (e.g. publish needs a token)
is_blocking(result) → boolWhether the result should fail CI (exit 1)
is_empty(context) → boolWhether there’s nothing to do (skip the LLM)
summary(result) → dictKey/values for the final done log line
needs_git (ClassVar)Whether preflight requires a .git repo (default False)
output_destination(settings, *, publish_enabled) → strSink shown in the done log

Output follows one rule for every runbook: without --publish the framework emits render_output() — raw result JSON, pipe-safe — to stdout/-o; with --publish the runbook’s custom publish() runs instead.

Built-in runbooks (the code-review family shares CodeReviewRunbook and differs only in collect + _post_to_platform):

Runbookcollect from--publish doesPublish requirements
local_reviewlocal git diffrenders pretty Markdown locallynone
github_pr_reviewGitHub PR + diffposts PR review commentsGITHUB_TOKEN, GITHUB_REPOSITORY, GITHUB_EVENT_NUMBER
gitlab_pr_reviewGitLab MR + diffposts MR note + inline threadsGITLAB_TOKEN, CI_PROJECT_ID, CI_MERGE_REQUEST_IID
bitbucket_pr_reviewBitbucket DC PR + diffposts PR comment + inline commentsBITBUCKET_URL, BITBUCKET_TOKEN, BITBUCKET_PROJECT, BITBUCKET_REPO, BITBUCKET_PR_ID
weather_advice (example)live weather API (no git)prints a Rich terminal panelnone

weather_advice exists to prove the frame fits any domain — it’s the template to copy for a non-code-review runbook. Full per-runbook settings + env: Configuration → Runbook reference.

One LLM driver — a single way of calling a model. The name fits: claudecode, codex, and pi are agentic CLIs, pydantic/deepagents are SDK drivers — Junior harnesses them rather than being the inference engine itself. Schema-agnostic: its one method, complete(*, system_prompt, user_message, output_schema, settings) → LLMResult, takes the output schema as a parameter, so the same harness serves every runbook. The validated schema instance is what makes deterministic publish possible — downstream code works with typed fields, never with free-form model text. Defined as the Harness ABC in src/junior/runbook/base.py; each harness module in src/junior/harnesses/ exposes a module-level HARNESS instance. Selected via --harness / llm.harness / env HARNESS.

Built-in harnesses:

HarnessInstallfile_accessAPI keyRuns via
claudecode (default)core✅ reads filesoptional (ANTHROPIC_API_KEY → API mode)the claude CLI
codexjunior[codex]✅ reads filesoptional (OPENAI_API_KEY)the codex CLI
pydanticjunior[pydantic]❌ diff inlinedrequired (OPENAI_API_KEY / ANTHROPIC_API_KEY)a single structured pydantic-ai call
deepagentsjunior[deepagents]❌ context inlinedrequired (OPENAI_API_KEY / ANTHROPIC_API_KEY)a LangChain orchestrator
picore✅ reads filesper provider — or none for local modelsthe pi CLI (incl. Ollama/LM Studio/vLLM)

file_access is a ClassVar[bool] on the harness: True means it explores the repository with its own tools, so the runbook doesn’t have to inline the full diff into the prompt (small diffs are inlined regardless); False means it only sees what’s in the message.

Full settings + env per harness: Configuration → Harness reference; per-harness deep dives in Harnesses.

[!NOTE] HarnessKind is the enum of harness names you select (--harness codex); the resolved object is a Harness instance. The old terms --backend / env BACKEND / config key backend still work as a deprecated alias for one version.