FAQ
Which harness should I use?
Section titled “Which harness should I use?”claudecode (default) if you use Claude Code; pydantic for cheap predictable CI runs;
codex for the OpenAI stack; pi for local models; deepagents is experimental. The
full decision table is Choosing a harness. The harness is
independent of the runbook (see below) — any harness serves any runbook. The old
--backend / BACKEND / backend: still work as deprecated aliases for --harness.
Which runbook should I use?
Section titled “Which runbook should I use?”The runbook picks the platform — collect → review → publish — and you choose it explicitly (--runbook NAME, config runbook:, or env RUNBOOK). There is no auto-detection and no implicit default: with nothing set, junior run exits 2.
local_review— reviews your local git diff and writes raw output to stdout /-o FILE.--publishrenders the review as pretty Markdown locally (no posting).github_pr_review— reviews a GitHub PR; posts comments with--publish. NeedsGITHUB_TOKEN,GITHUB_REPOSITORY,GITHUB_EVENT_NUMBER.gitlab_pr_review— reviews a GitLab MR; posts a note with--publish. NeedsGITLAB_TOKEN,CI_PROJECT_ID,CI_MERGE_REQUEST_IID.bitbucket_pr_review— reviews a Bitbucket Data Center PR; posts comments with--publish. NeedsBITBUCKET_URL,BITBUCKET_TOKEN,BITBUCKET_PROJECT,BITBUCKET_REPO,BITBUCKET_PR_ID.
To post a review to a PR/MR:
junior run --runbook github_pr_review --publish # GitHub PRjunior run --runbook gitlab_pr_review --publish # GitLab MRjunior run --runbook bitbucket_pr_review --publish # Bitbucket DC PRWhy did the review find nothing?
Section titled “Why did the review find nothing?”- Junior ships no task prompts — you pass them via
--prompt,--prompt-file, or config. With none, the LLM sees the diff,AGENT.md/CLAUDE.md, and code_review’s base rules only. - Use
junior dry-runto verify the diff isn’t empty. - Be specific:
--prompt "Find security vulnerabilities"beats vague asks. - Smaller models miss more — try a larger model with
--model.
Why is the review so expensive?
Section titled “Why is the review so expensive?”- Agentic harnesses (
claudecode,codex,deepagents) explore the repo, so they use far more tokens thanpydantic’s single structured call — switch harness if cost matters. - Fewer/shorter prompts → a smaller system prompt and fewer response tokens.
- Review smaller changes:
--source stagedor smaller MRs.
CI fails with exit code 1 — is that a bug?
Section titled “CI fails with exit code 1 — is that a bug?”No. Exit code 1 means blocking issues were found (critical severity or request_changes recommendation). Review the findings and either fix them or use allow_failure: true in CI config.
junior run --publish fails — what do I check?
Section titled “junior run --publish fails — what do I check?”- Runbook: posting to a PR/MR needs
--runbook github_pr_review,gitlab_pr_review, orbitbucket_pr_review. Onlocal_review,--publishjust renders Markdown locally (no posting) — that always works. - Platform token:
GITLAB_TOKEN(withapiscope) orGITHUB_TOKEN - Platform env vars:
- GitLab:
CI_PROJECT_ID,CI_MERGE_REQUEST_IID(auto-set in CI) - Bitbucket DC:
BITBUCKET_URL,BITBUCKET_PROJECT,BITBUCKET_REPO,BITBUCKET_PR_ID(set them in your CI) - GitHub:
GITHUB_REPOSITORY(auto-set),GITHUB_EVENT_NUMBER(map from${{ github.event.pull_request.number }})
- GitLab:
In GitLab CI these are auto-provided. In GitHub Actions, GITHUB_EVENT_NUMBER must be mapped manually — see CI Setup.
Many small prompts vs one big prompt — which is better?
Section titled “Many small prompts vs one big prompt — which is better?”All prompts merge into a single system prompt for one LLM call (details). Several focused prompts give the model clearer checklists; one combined prompt keeps the call cheaper.
How do I write my own prompts?
Section titled “How do I write my own prompts?”Three ways (CLI values append to config):
# Inline — repeatablejunior run --prompt "Check security" --prompt "Check error handling"
# File — repeatable, .md onlyjunior run --prompt-file ./rules/api.md --prompt-file ./rules/naming.md
# Config — single context.prompts list (inline text or "file://..." URI) in# .junior.yaml, ~/.config/junior/settings.yaml, or any file passed via --configSee examples/prompts/ for five reference prompts to copy. Prompts has format details.
How do I review without publishing?
Section titled “How do I review without publishing?”junior run --source branch -o review.md # generate locally, inspectjunior run --runbook github_pr_review --publish-file review.md # publish that .md when ready (or gitlab_pr_review)Where does Junior save what it did?
Section titled “Where does Junior save what it did?”Every successful junior run writes a run record to <project_dir>/.junior/output/{timestamp}.json — a secret-free JSON snapshot of the run: runbook, harness, model, token usage, errors, summary, blocking flag, and the structured review output. It’s on by default; turn it off with --no-record or output.record: false. .junior/ is gitignored, so records never get committed.
Can I pipe the review into another tool?
Section titled “Can I pipe the review into another tool?”Yes. Without --publish, stdout carries exactly one JSON document matching the
runbook’s schema — status, progress, and logs all go to stderr — so
junior run > review.json or junior run | jq .comments captures only the result.
With --publish on local_review you get the human-readable Markdown instead.
How do I tweak settings for a single run without editing config?
Section titled “How do I tweak settings for a single run without editing config?”Use junior run -i (or --interactive). It walks you through harness, model, source, target branch, and output target with your current config as the default — press Enter to keep, type to override. Prompts are not part of the wizard (pass via --prompt / --prompt-file or set in config). Nothing is written to disk; the choices apply only to this run. Use junior init instead if you want to persist them.
How do I review a remote MR locally?
Section titled “How do I review a remote MR locally?”You can review (and publish to) any GitLab MR or GitHub PR from your laptop — including self-hosted GitLab. In CI most of these variables are set automatically; locally you set them yourself.
GitLab (gitlab.com or self-hosted)
Section titled “GitLab (gitlab.com or self-hosted)”1. Clone the repo and check out the MR’s source branch
git clone <repo-url> && cd <repo>git fetch origin "merge-requests/<IID>/head:mr-<IID>"git checkout mr-<IID><IID> is the MR number (/-/merge_requests/<IID> in the MR URL). The fetch above works without knowing the source branch name.
2. Find the project ID
Either via the UI: open the project page → ID is shown under the project name (also under Settings → General → “Project ID”).
Or via the API:
curl -s -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "https://gitlab.example.com/api/v4/projects/<owner>%2F<repo>" | jq '.id'3. Set the env vars
export GITLAB_TOKEN=glpat-... # api scope (read+write for --publish)export CI_SERVER_URL=https://gitlab.example.com # only needed for self-hosted; default is gitlab.comexport CI_PROJECT_ID=<numeric id from step 2>export CI_MERGE_REQUEST_IID=<MR number>export CI_MERGE_REQUEST_TARGET_BRANCH_NAME=master # default is "main"The token must be issued on the same instance you’re targeting. A gitlab.com token won’t work against a self-hosted instance and vice versa.
4. Run
junior run --source branch -o review.md # generate locally, inspect firstjunior run --runbook gitlab_pr_review --publish-file review.md # post the summary as an MR noteGitHub (github.com)
Section titled “GitHub (github.com)”gh pr checkout <PR-number> # or: git fetch + checkout manuallyexport GITHUB_TOKEN=ghp_...export GITHUB_REPOSITORY=owner/repoexport GITHUB_EVENT_NUMBER=<PR number>junior run --runbook github_pr_review --source branch --publish- Inline (per-line) comments are skipped locally. GitLab needs
CI_MERGE_REQUEST_DIFF_BASE_SHAandCI_COMMIT_SHAto anchor each finding to the diff. CI sets them; locally they’re empty, so Junior posts a single summary note instead. Set both manually if you want inline comments:Terminal window export CI_COMMIT_SHA=$(git rev-parse HEAD)export CI_MERGE_REQUEST_DIFF_BASE_SHA=$(git merge-base origin/master HEAD) - For repeated runs, put the env vars into
.junior.yaml(project-local) or~/.config/junior/settings.yaml(global). Same keys work —gitlab_token,ci_server_url, etc.