Greenhorn is a literal newcomer for your repository, on demand. It sends your README and its explicitly linked documentation to a fresh Codex scratch session, one turn at a time. Codex can propose one plain command; a separate GPT-5.6 contract enforcer (Azure AI Foundry or the OpenAI API) allows or blocks it before Greenhorn's pristine Docker executor can run it.
The report preserves the documentation quote, ruling, command result, dead end, verified checkpoint, and time-to-first-green-build (TTFGB).
Greenhorn's core was built inside Codex, powered by GPT-5.6. The Node orchestrator, the contract-enforcer client, the report renderer, the checkpoint and fix-loop logic, and the test suite were all written and iterated in Codex sessions rather than by hand — GPT-5.6 drafting and revising the implementation turn by turn while the design decisions stayed with me.
Codex is also the constrained newcomer runtime inside the product: Greenhorn
launches codex exec in a fresh, empty scratch session and lets it propose
exactly one plain command per turn from the documentation alone.
GPT-5.6 is the independent contract enforcer. On every non-bypass proposal
it rules the command LICENSED, AMBIGUOUS, or INFERENCE against the docs
before any shell exists, and for a supported documented halt it drafts the
minimal README addition anchored to the transcript. GPT-5.6 runs through Azure
AI Foundry or the direct OpenAI API; every report and transcript records which
provider and model actually ruled.
The two are deliberately separated: Codex reasons and proposes, GPT-5.6 rules,
and only a LICENSED command reaches the pristine Docker executor. Every report
shows this decision trail per command, so a reviewer can see exactly where each
model acted.
The checked-in seven-run public Node pilot always opens without Docker or credentials. It leads with two verified green paths (Express and page.js), and carefully labels the remaining five outcomes. It is a pinned product pilot, not an “X of N READMEs fail” prevalence claim.
The live Express report records a 2026-07-18
run at ae6dd376: Codex proposed two commands, GPT-5.6 Luna ruled them, and the documented test exited zero in fresh Docker in 1.1 minutes.
The live doc-fix proof is a separate controlled Node fixture, included to show the complete mechanism rather than make a prevalence claim: a literal halt, the Azure GPT-5.6 Luna README draft, and a disposable fix-snapshot rerun that independently verifies the documented output marker.
The fixture report and A/B fixture
are explicitly seeded explanations of the mechanism, never live-repository
results. The A/B page links a real captured unconstrained Codex command trace,
but the repository itself remains a seeded fixture. The included deployment
workflow publishes docs/ as the zero-setup
judge path whenever GitHub Pages is enabled with GitHub Actions as the
source.
See SUBMISSION.md for the evidence gates, a truthful
under-three-minute recording outline, and the final publishing checklist.
Existing DX tools can score onboarding from artifacts in a developer's stateful environment. Greenhorn executes one literal documented path in a barren container and shows every command decision.
Codex is the newcomer runtime. Greenhorn launches codex exec in a new empty
scratch directory with a read-only sandbox; the target repository is not its
working directory and is never named in its prompt. The GPT-5.6 contract
enforcer resolves Azure AI Foundry when it is configured, otherwise the direct
OpenAI API; it sees only the docs, proposed command, and compact repository
state to issue an independent ruling. Greenhorn alone has command-execution
authority in the container.
This is a cooperative, auditably constrained model setup—not a hard filesystem barrier against a malicious model. Every shell command that actually ran is in the transcript, and rejected commands are recorded before a shell process is created.
- macOS or Linux (Windows is untested and unsupported in this build)
- Node 20+ (no project npm dependencies are needed)
- Docker Desktop, running
- An authenticated Codex CLI (
codex login statusto check) - Either an Azure AI Foundry deployment named
gpt-5.6-lunaand its endpoint/key, or anOPENAI_API_KEYwith access toOPENAI_MODEL
This build evaluates only repositories with a root package.json. Flutter,
Rust, Go, Python, Java, Ruby, and documentation-only repositories are reported
as UNSUPPORTED RUNTIME; they are never scored as README failures.
Copy the example and configure one GPT-5.6 provider. .env is ignored by Git.
cp .env.example .env# Option A — Azure AI Foundry. Copy this exact inference endpoint from
# Foundry → deployment → Details.
AZURE_OPENAI_ENDPOINT=https://your-resource.services.ai.azure.com
AZURE_OPENAI_API_KEY=your_key_here
AZURE_OPENAI_DEPLOYMENT=gpt-5.6-luna
AZURE_OPENAI_API_VERSION=2024-10-21
AZURE_OPENAI_API_STYLE=auto
# Option B — direct OpenAI API. Judges: this is the fastest live path when
# your API key has model access. Leave all Azure values blank to use it.
OPENAI_API_KEY=your_key_here
OPENAI_MODEL=gpt-5.6
OPENAI_BASE_URL=https://api.openai.com/v1
# Optional: Codex model used for the constrained newcomer and baseline capture.
GREENHORN_CODEX_MODEL=gpt-5.6-terraAZURE_OPENAI_API_STYLE=auto tries the documented Azure deployment, OpenAI/v1,
and Foundry Models surfaces against the endpoint you supplied. If Azure returns
Resource not found, recopy the endpoint and deployment name from Foundry
Details rather than guessing a hostname.
When both providers are configured, Azure intentionally wins so an existing Foundry setup does not change behavior. Bring your own OpenAI API key with access to the selected model: the checked-in live pilot is Azure-backed, and a Codex login does not imply OpenAI API model entitlement.
Check the setup without revealing credentials:
node ./bin/greenhorn.mjs doctor
node ./bin/greenhorn.mjs doctor --verify-enforcer
codex login statusThe second command makes one tiny GPT-5.6 request. It is the prerequisite for
a live run; a configuration-only doctor does not prove the selected provider.
--verify-azure remains an alias for existing scripts.
doctor also confirms that the Docker daemon is reachable, but it does not
pull or build the Greenhorn runtime image. See the first-run note below before
expecting a fresh machine to complete an audit.
# Local repository
node ./bin/greenhorn.mjs run /absolute/path/to/your/repo
# Public Node repository
node ./bin/greenhorn.mjs run https://github.com/owner/repository.gitEach run prints the exact report.html and transcript.json paths. On macOS:
open /printed/path/to/report.htmlDocker is the default because it creates the pristine command executor. A Git
URL is shallow-cloned into Greenhorn staging, copied into a new Ubuntu 24.04
container, and never executed on the host. --runtime host is only for local
transport debugging and must not be presented as isolation proof.
On a machine without the runtime image, Greenhorn builds
greenhorn-runtime:local before it audits a repository. The first build needs
Docker Desktop to download ubuntu:24.04 and install the runtime dependencies,
so it can take a few minutes and requires network access. This is a runtime
bootstrap step, not part of the repository verdict.
If a run stops while fetching ubuntu:24.04 (for example, with a Docker
DeadlineExceeded error), verify and warm the runtime explicitly, then retry:
docker pull ubuntu:24.04
docker build --progress=plain -t greenhorn-runtime:local -f Dockerfile .
node ./bin/greenhorn.mjs run https://github.com/owner/repository.gitIf the pull or build fails, check Docker Desktop's network connection and the
container registry before retrying. Treat it as RUNTIME ERROR, not a finding
about the repository being audited. Do not switch to --runtime host merely to
work around a Docker failure if you need isolation-backed evidence.
The whole run defaults to 30 minutes; each accepted command receives up to
eight minutes. TIMEOUT is never reported as a documentation dead end.
greenhorn demo [--out outputs/hero-report.html]
greenhorn ab-demo [--out outputs/ab-demo.html]
greenhorn baseline [fixture-path] [--timeout-minutes 8]
greenhorn doctor [--verify-enforcer] [--verify-azure]
greenhorn run <path|git-url> [--runtime docker|host] [--enforcer gpt|heuristic] [--timeout-minutes 30] [--command-timeout-minutes 8] [--external-docs]
greenhorn rerun --with-fix <run-directory> [--runtime docker|host] [--enforcer gpt|heuristic] [--external-docs]
greenhorn ci <path> [--runtime docker] [--enforcer gpt|heuristic] [--external-docs]
The default --enforcer gpt uses Azure GPT-5.6 Luna when Azure is configured;
otherwise it uses the direct OpenAI API model named by OPENAI_MODEL, for every
non-bypass ruling. The run transcript and report record which provider and
model actually ruled. --enforcer heuristic is a deterministic local fallback:
it runs the same constrained flow without any model credential, and every
report labels its rulings as heuristic rather than GPT-5.6. Use it to exercise
the mechanism when no GPT provider is available; headline results always come
from the GPT enforcer.
By default Greenhorn reads the README plus explicitly linked local docs only, to a link depth of 2 and a maximum of 6 documents. It does not search the web.
Pass --external-docs to opt in to explicitly linked HTTP(S) pages. Those
pages still count toward the same depth and document caps, are size- and
time-limited, and redirects are rejected. Greenhorn never follows arbitrary
search results or unlinked URLs.
Greenhorn accepts only LICENSED actions. AMBIGUOUS and INFERENCE actions
are blocked before the shell receives them. Safe reads (pwd, simple ls,
version checks, and cat of a licensed doc) skip the model ruling.
A claimed success is not a green result by itself. Greenhorn verifies either a
documented localhost endpoint with orchestrator-controlled retries, a documented
build/test command that exited 0, or a documented output marker produced by its
licensed verification command in the isolated executor. An unsuccessful
verification is reported as CHECKPOINT FAILED, not COMPLETED.
NO DOCUMENTED CHECKPOINT is distinct: a documented setup command completed,
but the README gives no repository test, endpoint, or output marker to verify.
It is a documentation-observability finding, not a README-failure verdict.
For a blocked setup step, the configured GPT-5.6 enforcer drafts a minimal
README append anchored to the transcript. greenhorn rerun --with-fix <run-directory> applies that reviewed draft only to a disposable snapshot,
then re-runs the same constrained flow. It never changes the source repository.
greenhorn ci makes a fresh stability re-run and fails only when a DEAD END
reproduces. The two passes use separate container, repository, and enforcer
cache state so a cached ruling cannot mask nondeterminism.
The included GitHub Action is an experimental hosted-runner template: its
non-interactive Codex authentication has not yet been verified on GitHub-hosted
runners. It additionally needs a non-interactive Codex credential
(CODEX_API_KEY or CODEX_ACCESS_TOKEN) plus the Azure variables; hosted
runners cannot reuse your desktop's Codex login. The template currently uses
Azure variables; direct OpenAI support is available for local and judge runs.
See
.github/workflows/greenhorn.yml.
npm test
npm run demo
open outputs/hero-report.html
# Heuristic labels, no GPT-provider request
npm run eval
# GPT-5.6 labels, after doctor --verify-enforcer passes
npm run eval -- --enforcer gpt
# Run only the held-out set after tuning rules
npm run eval -- --enforcer gpt --set reportThe fixture report is labeled as a deterministic seeded fixture; it is not presented as a live repository evaluation. The contract tune and report sets are disjoint. Repository statistics belong in the evaluation only after a pinned commit, transcript, and reproducible Docker run exist.
greenhorn baseline [fixture-path] captures a separate unconstrained Codex
session in a disposable copy of a fixture, then writes its actual command trace
under .greenhorn/baselines/. greenhorn ab-demo emits the equally labeled
seeded A/B page used to explain why an unconstrained workflow can hide a
missing instruction. The baseline deliberately uses convenient host developer
tools, whereas Greenhorn executes in Docker; it is a behavioral contrast, not
an isolation benchmark. Neither is a live-repository result.
This does not claim that nobody measures setup. CSR-Bench, DeployBench,
build-bench, and SWE-bench++ cover related containerized setup tasks, while
gstack's /devex-review audits developer experience from artifacts.
Greenhorn's narrower product claim is an installable, re-runnable doc-fix loop
with a constrained newcomer, visible per-command decisions, a pristine command
executor, and a stability-gated CI check.