@barmajja/jclaude
v0.7.0
Published
External controller that wraps the Claude Code CLI and uses the Jev router (via OpenRouter) for narrow structured routing decisions. Stage 1 and the start of Stage 2 only. See README.md.
Readme
jclaude
An external controller/launcher that wraps the official Claude Code CLI and uses an LLM router
called Jev (accessed via OpenRouter's POST /api/v1/systemone endpoint) to make narrow,
structured routing decisions — which Claude model/effort to use for a task, whether it's
ambiguous, whether it looks sensitive — before handing off a compact task to a normal Claude
Code worker process.
Jev never generates code or text. It only answers typed Choice/Score/Noul questions with a confidence value. Every piece of prose, code, or reasoning in a routed task still comes from the Claude Code worker Jev routed to — Jev's whole job is picking which worker and how hard.
This is Barmajja/barmajja-aios, a standalone repo. It started life under tools/jclaude/ in
barmajja/barmajja (see "History" below for why) and was copied here unchanged once this repo
could be created. It is additive and opt-in: nothing in barmajja/barmajja or any other
Barmajja repo imports it, references its path, or runs it automatically. See Rollback below.
Scope: what got built
This build now implements Stage 1 (inspection, offline tests, shadow/dry-run routing),
Stage 2 (opt-in startup model/effort routing, compact context retrieval, log reduction,
truthful telemetry), and Stage 3 (approved memory retrieval, selective skills/tests,
duplicate suppression, bounded escalation) of the design brief (full text,
verbatim, as given 22 Sep 2026), plus jclaude auth login/logout — a real credential path
(headless PKCE OAuth against OpenRouter) for the OPENROUTER_API_KEY every stage above assumes
but never had a way to obtain other than pasting one in by hand. Explicitly out of scope, per the
brief's own staging and this repo owner's instruction:
- Stage 4 — a generative helper model, narrowly scoped operational integrations, a remote (non-local-CLI) interface.
- Module H (review intensity/completion certification) and Module J (routine operations/scheduled jobs — the brief explicitly says not to add these in this pass).
- Any real embedding model, vector database, or additional agent framework — Module D's memory retrieval and Module G's near-duplicate check are both offline token-set Jaccard similarity, per the brief's own instruction not to add a vector database without a demonstrated requirement (and there is still no LLM key to call one with regardless).
- Anything that calls a live OpenRouter/Jev endpoint, or spawns a real nested
claudeprocess — see "What's unverified" below, which this stage's build extends rather than shrinks.
A stub for Stage 4 lives in src/stubs/stage4.ts — each function throws immediately with a
message pointing back here. Nothing calls it. src/stubs/stage3.ts has been deleted: Stage 3 is
implemented for real now, in src/memory/, src/skill-catalog/, src/test-selector/,
src/repair-loop/, src/run-lock/, and an addition to src/ledger/ — see the modules table.
Modules
| Module | Path | Responsibility |
|---|---|---|
| config | src/config/ | Typed config: jclaude.config.json (committed defaults) + .env (secrets/overrides), validated with zod |
| jev-client | src/jev-client/ | Typed HTTP client for the Jev endpoint, plus an offline MockJevClient. Injectable transport. |
| decision-contract | src/decision-contract/ | Choice/Score/Noul question builders, the routing state object, and secret redaction |
| policy | src/policy/ | Turns Jev's answers (or their absence) into a RoutingDecision: model/effort table, fallback, escalation, explicit-override handling |
| context-packer | src/context-packer/ | Bounds the routing state to a rough estimated-token budget, truncating evidence (never task/policy text) |
| log-reducer | src/log-reducer/ | Runs a command, captures full output to a log file, returns a concise pass/fail result with the real exit code |
| ledger | src/ledger/ | SQLite (node:sqlite) or a JSON-file fallback: per-task decision record, fingerprint-based idempotency, cache invalidation on a changed working tree. near-duplicate.ts (Stage 3, Module G addition) adds offline near-duplicate flagging on top of the existing exact-fingerprint dedup. |
| memory | src/memory/ | Stage 3, Module D. Persistent structured project memory (architecture decisions, command recipes, reproducible defects, failed approaches, verified-solution refs) — SQLite/JSON-fallback store, strictly scoped retrieval by project (+subsystem), working-tree-hash-based staleness invalidation. Never a transcript: body length is capped by both config and a hard schema ceiling. |
| skill-catalog | src/skill-catalog/ | Stage 3, Module C. A short, typed, committed catalog of approved skills/tools (jclaude.config.json's skillCatalog). nominate.ts asks Jev (name+description only, never full skill text) or falls back to an offline keyword matcher. authorize.ts is the mandatory gate — a nomination is never itself authorization; only authorizeSkill() can produce the branded AuthorizedSkill type, and it requires the name to be in both the catalog and the separate allowedNames permission list. |
| test-selector | src/test-selector/ | Stage 3, Module E. Config-driven glob→suite mapping over changed files (selectFastCheckSuites) plus a fully deterministic looksSensitive() classifier (paths + keywords) that unconditionally forces the mandatory full suite — evaluated before fast-check selection even runs, so a model can never be the sole reason a required check gets skipped. changed-files.ts wraps git diff --name-only <base> behind an injectable GitExec. |
| repair-loop | src/repair-loop/ | Stage 3, Module F. The actual attempt → verify → retry → bounded-escalate orchestration loop that consumes config.repair's previously-unused maxFailedRepairs/maxAutoEscalations numbers. classify.ts deterministically detects auth/permission/missing-credential/unsupported-platform failures, which stop the loop rather than escalate. Every attempt preserves a read-only diff snapshot (diff.ts, never a reset) and a stable error fingerprint. |
| run-lock | src/run-lock/ | Stage 3, minimal Module I (explicitly scoped down per the brief: no distributed lock service). One lockfile per repo's state dir, live-pid-checked, preventing two concurrent jclaude run invocations against the same repo path. |
| text-similarity | src/text-similarity/ | Shared offline tokenize/Jaccard-similarity helpers used by both memory/retrieve.ts and ledger/near-duplicate.ts. No embeddings, no vector DB, no network call. |
| auth | src/auth/ | Headless PKCE OAuth against OpenRouter's /auth and /api/v1/auth/keys endpoints (jclaude auth login/logout). Exchanges a short-lived authorization code for a real key without the raw key ever passing through a Claude Code session — see "Getting an OpenRouter key" below. |
| cli | src/cli/ | jclaude doctor / route / run / resume / report / memory {list,add,invalidate} / auth {login,logout}, built on commander. route/run now also fold in memory evidence, near-duplicate flags, and skill nomination; run --repair engages the Stage 3 repair loop. |
Setup
npm install
npm run build # compiles src/ -> dist/, which bin/jclaude.mjs runs
npm test # 216 tests, all offline/mocked — see "What's verified live" belowCopy .env.example to .env if you want to try a live Jev call yourself (see "Getting an
OpenRouter key" below) — .env is gitignored either way.
Getting an OpenRouter key: jclaude auth login
Run this yourself, on your own machine — not inside a Claude Code session:
node bin/jclaude.mjs auth loginThis does OpenRouter's headless PKCE OAuth flow (their docs link to it, and it's the one explicitly meant for "SSH Servers, Containers" — exactly this situation):
jclaudegenerates acode_verifier/code_challengepair locally and prints an authorization URL.- You open that URL in your own browser and approve access. OpenRouter displays a short-lived (10 minute), single-use authorization code on screen — it never redirects anywhere, since there's no callback URL a headless process could receive.
- You paste that code back into the
jclaude auth loginprompt. jclaudeexchanges the code (plus thecode_verifieronly it has) for a real API key, and writesOPENROUTER_API_KEYstraight into your local.env.
The raw key is never printed, never logged, and never returned to any caller — runAuthLogin()
(src/auth/login.ts) only ever hands back a sha256 fingerprint (safe to share; not reversible to
the key), which is also all doctor or any log line would ever show. This matters specifically
because the authorization code is short-lived and single-use by design, but the key it
exchanges for is a persistent credential — the brief this project implements is explicit that a
real key must never appear in a prompt, a log, or a repository, and running this locally rather
than having an AI session perform the exchange is what actually guarantees that.
jclaude auth logout removes OPENROUTER_API_KEY from .env (it does not revoke the key on
OpenRouter's own dashboard — do that separately if you want the key itself dead, not just unused
locally).
Run the CLI either via the build:
node bin/jclaude.mjs doctor
node bin/jclaude.mjs route "add a footer link" --project barmajja --subsystem websiteor directly against TypeScript during development (no build step):
npm run cli -- doctordoctor, --dry-run, and --live — what each actually does
jclaude doctoris read-only. It checks: whether theclaudeCLI is onPATHand its version; OS info; git repo state (HEAD, dirty/clean); whetherjclaude.config.jsonparses and validates; whethernode:sqliteis available; and whether an OpenRouter key is present — as a boolean only, never printed. It never writes a file, opens a database, or makes a network call.jclaude route "<task>" [--dry-run]runs the full decision pipeline (redact → pack → ask Jev → apply policy) and prints the result. It never launches a worker, dry-run or not — that's whatrunis for. By default it usesMockJevClient, an offline stand-in whose default resolver answers every question withconfidence: 0, so an unconfigured route fails closed (pauses for review) rather than looking confident about nothing. The output is always prefixed[MOCK]or[LIVE]so it's never ambiguous which one ran.--liveswitches to a realJevClientagainst the configured OpenRouter endpoint. It requiresOPENROUTER_API_KEYto be set and refuses immediately (not a silent fallback to mock) if it isn't. Exercised for real on 22 Sep 2026 (two manual calls) — see "What's verified live" below for exactly what that does and doesn't establish.jclaude run "<task>" [--model X]either routes (as above) or, given an explicit--model, bypasses Jev entirely. An explicit override is always honored or the CLI explains exactly why not (disallowed profile, fable without budget opt-in, unknown model string) — it is never silently substituted for something else. If routing resolves toreview-pauseorexisting-tool, nothing is launched.jclaude resume <task-id>looks up a task's ledger record and reports whether its cached decision is still valid (working tree unchanged) or stale.jclaude report [--json]summarizes the ledger, explicitly separating measured telemetry (tokens/cost the provider actually returned) from unknown (mock calls, or a provider that didn't return usage) — a mock call's cost is reported as unknown, never as$0.jclaude run "<task>" --repair(Stage 3, Module F) — on a worker failure, runs the bounded repair/escalation loop instead of stopping after one attempt: retries at the same model tier up torepair.maxFailedRepairs, then auto-escalates one tier up torepair.maxAutoEscalationstimes, and stops instead of escalating on an auth/permission/missing-credential/unsupported- platform failure. Off by default — plainrunkeeps its original single-attempt behavior.jclaude memory list|add|invalidate(Stage 3, Module D) inspects and manages the persistent project-memory store directly, e.g.:node bin/jclaude.mjs memory add --project barmajja --subsystem website \ --kind reproducible-defect --title "RTL skip-link overflow" \ --body "left:-9999px overflowed in RTL and blanked every Arabic page — use transform instead" \ --tags rtl,css node bin/jclaude.mjs memory list --project barmajja --query "arabic page blank" node bin/jclaude.mjs memory invalidate --project barmajjaroute/runalready consult this store automatically (scoped to--project/--subsystem), folding relevant records in as ordinary evidence subject to the same redaction and context-packer budget as everything else —memory addis for recording something new by hand or from a reviewed worker output, not a required step before routing works.
What's verified live, and what still isn't
Updated 22 Sep 2026: a real OpenRouter key was obtained via jclaude auth login (run from an
ephemeral session, per the flow described above) and used for two manual route --live calls
against the real endpoint. That changed several things this README previously called permanently
unverified — and it also caught a real bug, which is worth being explicit about rather than
quietly fixing and moving on:
The first live call failed. The wire request/response schema this codebase had built against — based on the design brief's own high-level description plus a paraphrased reading of OpenRouter's docs — was wrong on several points the docs summary didn't make clear enough to catch in advance:
questionsandanswersare objects keyed by question id, not arrays.stateis a plain string, not the structured JSON object this codebase'sRoutingStatenaturally is (now serialized to a string only at theJevClient.ask()wire boundary — everything upstream of that, redaction/context-packing/memory-folding, still works on the structured object).- A Score question takes an ordered array of qualitative level labels (
criteria), not a numeric{min, max}range. - Noul answers are a bare 0-1 probability with no separate
confidencefield. Choice/Score answers carry aconfidenceJev computes itself from the answer's probability distribution — which is also why this codebase no longer asks a standalone "how confident are you" question; it reads.confidenceoff themodel_profileChoice answer directly instead. - A response's
modelfield can carry a dated resolution suffix (e.g.typesafe/jev-1.13-20260917for a request oftypesafe/jev-1.13) — the client now accepts an exact match or a"<requested>-…"prefix, not exact-string-only, so a legitimate pin resolution doesn't get rejected as if it were a silent model substitution.
src/jev-client/types.ts now has the actual, empirically-confirmed wire schema (JevWire*
types) alongside the ergonomic internal shape everything else in this codebase uses; that
conversion happens in exactly one place (client.ts). This is precisely the failure mode this
build was designed for — JevClient's strict validation rejected the malformed response rather
than silently proceeding — but it's also a concrete reminder that a doc summary (even from the
docs themselves) is not the same as verifying against a real response.
Confirmed live, now, on real calls (not just tests against mocks):
- The corrected request/response schema round-trips successfully —
route --livecompleted, returned a sensiblehaiku-profile decision with real confidence numbers, and recorded it in the ledger. - Module C (skill nomination) was live-exercised too —
route's Jev client is shared withnominateSkill(), so both manual live calls asked the real endpoint to nominate from the 4-entry catalog injclaude.config.json, not just a mock. - Real telemetry flows through end to end:
jclaude reportshows real measured input/output tokens and cost (small — a few hundred tokens, fractions of a cent) for these calls, correctly distinguished from the still-unknowntelemetry of the one failed call before the fix. - The near-duplicate check (Module G) correctly flagged the second manual call as a near-duplicate of the first, using real task text through the real pipeline.
Since then: a 36-task live pilot (§"Evaluation plan" below,
full report) found and fixed a real over-pausing bug (the
ambiguous threshold), confirmed live with a 16-task follow-up batch — 52 live route --live
calls total, $0.0016 cumulative cost, 0 errors, 0 unknown-telemetry records.
run --live cannot be exercised from inside a Claude Code session at all — discovered by
trying it, 22 Sep 2026. The default launcher shells out to a real claude -p subprocess
(defaultLauncher in src/cli/commands/run.ts). Attempting that from within this project's own
Claude Code session was refused outright by the session's own permission system, category
"Create Unsafe Agents" — a nested-agent-spawning guardrail, not a bug in jclaude, and not
something to route around (a different subprocess mechanism to spawn claude would just be
re-attempting the same blocked thing under a different name). Nothing executed: the refusal
happened before the command ran, so no partial state, no ledger record, no wasted Jev call.
What this means architecturally, not just operationally: run --live needs to be run from an
ordinary shell — a terminal, a CI job, anything that is not itself a Claude Code session — same
as jclaude auth login needed to run outside a session for its own (different) reason. This
isn't a gap to close later; it's close to definitional for a tool whose whole premise is
external to Claude Code. Worth stating plainly so nobody spends time trying to make run --live
work from inside a session — by design, it can't.
23 Sep 2026, from an ordinary terminal (Abdulla's own laptop, not a session): run --live
finally launched a real claude -p worker — no nested-agent guardrail here. It still didn't
change anything: claude -p has no TTY to approve a file edit, so it printed "I need your
permission to edit the .gitignore file..." and exited 0 having done nothing. The ledger had
recorded that as outcome: "success" — a real bug, fixed the same day (classifyRunOutcome()
in src/cli/commands/run.ts; compares the working tree's hash before/after the real launcher
runs, since exit code alone was never evidence anything happened). Reconfirmed live after the
fix: same task, same permission block, now correctly recorded as no-op.
The obvious next question — let the worker bypass permissions so it can actually finish — was
asked and explicitly declined, 23 Sep 2026. run --live's practical ceiling stays "ask and
stop" rather than "act unsupervised": no --dangerously-skip-permissions or equivalent on the
nested worker, not scoped to specific paths, not at all. This is a deliberate policy decision,
not a gap — do not add a bypass later without going back to Abdulla for it specifically; this
paragraph existing is the record that it was considered and turned down once already.
Still unverified:
run --livehas launched a real worker twice now (both from a real terminal, 23 Sep 2026) but never completed a task that actually needed to change files — both hit the permission gate described above, which is the intended behavior, not a bug, per the 23 Sep decision to keep it gated. What's still genuinely unverified: arun --livetask that doesn't need file edits (a read-only investigation, a question), and — by explicit design choice — anything requiring unattended file edits, since that path is deliberately not being built.run --repairdriving several real nestedclaudeinvocations back to back remains untested against a real subprocess — everyrun/routetest still injects a fakelauncher, and the one real repair scenario that would exercise it (a permission block) now correctly stops the loop on attempt 1 rather than retrying, so it's never had a reason to run a second real attempt.- Module D (memory) retrieval quality at real scale, and Module G's 0.6 near-duplicate threshold, remain unvalidated against a real multi-week corpus — the live calls exercised the mechanism, not its tuning.
src/run-lock/has never been exercised under real process concurrency (tests inject a fakeisPidAlive).jclaude auth login's own PKCE round-trip has now been exercised for real (see "Getting an OpenRouter key" above) — that gap is closed. What's still unverified there specifically is everything error-path: an expired code, a revoked/invalid code, or OpenRouter changing its/api/v1/auth/keysresponse shape, none of which happened to come up in the one successful run.
jclaude doctor remains the right first thing to run in a new environment (reports
OpenRouter API key present: yes/no without ever printing the value) before attempting
route --live.
Evaluation plan (steps 1–2 now run once; 3–6 still design)
It follows the design brief's own suggested pilot methodology:
- Pilot size: 30–50 real tasks pulled from ordinary work in this repo or its siblings
(
tools/review-bot-style scripting, small doc/content edits, config changes) — enough to see the distribution of profiles Jev picks without needing a huge sample, small enough to review every decision by hand. Run once, 22 Sep 2026: 36 tasks, drawn from real commit history acrossbarmajjaand its siblings — seedocs/pilots/2026-09-22-live-eval.md. - Shadow mode first: run
route --live(notrun) on each pilot task. Record every decision in the ledger without ever launching a worker off it. This validates the client and schema against the real endpoint with zero execution risk. Done for all 36 — 0 errors, real telemetry (~$0.0011 total), the schema fix above is a direct product of this step. - Human-reviewed accuracy check: for each of the 30–50 shadow decisions, a human classifies it as reasonable / too conservative (should have picked a cheaper profile) / too aggressive (should have paused or picked a stronger profile). This is the number that actually matters — not "did it run," but "was the profile it picked defensible." Not done — the pilot report has my own first-pass read per row, explicitly flagged as a starting point, not a substitute for this.
- Sensitive/ambiguous recall: deliberately include a handful of tasks from the pilot set
that should pause (touch anything on the "never assert" list in the root
CLAUDE.md, or are genuinely underspecified) and confirm Jev'ssensitive/ambiguousanswers catch them. Missing one here is the costly failure mode, not routing a normal task to the wrong tier. Done twice: the 36-task pilot found theambiguousthreshold over-triggered on 9 terse-but- clear real tasks; fixed (threshold split,AMBIGUOUS_YES_THRESHOLD=0.75) and reconfirmed live on a 16-task batch (the 9 false-pauses + all 10 sensitive/ambiguous controls) — 8/9 fixed, the 1 holdout was a legitimate sensitive catch, both control groups held 100% recall throughout. See the pilot report's addendum. - Only then,
run --liveon a small subset (5-10 of the reviewed-reasonable tasks), with a human watching, to validate the handoff to the Claude Code worker end to end — modeled afterresume/reportreading back a real telemetry number for the first time. Attempted 3 times total: once 22 Sep 2026 from inside a Claude Code session (refused outright by that session's own nested-agent guardrail, nothing ran), twice more 23 Sep 2026 from a real terminal (both launched a realclaude -pworker, both hit Claude Code's own permission gate on the file edit and correctly stopped — the second confirmed a reporting bug found by the first is now fixed). Still no task has completed an actual file edit — and per the 23 Sep decision above, won't, unless the permission gate is revisited later. This step is as "done" as it's going to get without that. - Cost/latency baseline: once step 5 has run,
reportwill finally have real numbers to show instead of "unknown" — that's the point where a cost-per-task baseline becomes meaningful, not before. Partial: real per-call cost/token numbers exist now (step 2 produces them too), but norun --livenumbers, so worker-side latency/cost is still unknown.
Global wrapper (shell/claude-wrapper.zsh) — opt-in, machine-wide, explicitly requested
Everything above is invoked deliberately, per task, via jclaude. This is different: a claude
shell function, sourced from ~/.zshrc, that shadows the real claude binary on this specific
machine — every terminal, every repo, including work that has nothing to do with Barmajja.
This is the one piece of this build that goes against the design brief's own explicit guidance ("preserve the original claude command," stated twice). It exists because Abdulla asked for exactly this, after being shown that conflict directly and confirming he meant it anyway (23 Sep 2026) — not a default, not something to replicate onto another machine or account without asking again.
Scope is deliberately narrow, for a structural reason, not a policy one: only
claude -p "<task>" (print/one-shot mode) gets routed. Claude Code hooks cannot swap which model
a session uses — UserPromptSubmit can only add context or block a prompt (see §8's own note on
this) — so there is no mechanism, hook-based or otherwise, that could route a plain interactive
claude session before you've typed anything. Bare claude, -c, --resume, --help,
--version, and any invocation without -p, pass straight through untouched.
Safety properties, verified 23 Sep 2026 against a fake claude binary (never a real session)
before this ever touched the real shell config:
JCLAUDE_WRAPPER_DISABLE=1(or a missing jclaude install, or nonodeon PATH) skips everything — real claude, original args, no exceptions.- Any Jev/jclaude failure — timeout, error, unparseable output — falls through to plain claude,
unchanged. jclaude's own configured Jev timeout (
jclaude.config.json, 8s) already bounds a live call; a Jev failure resolves to a valid fallback decision, not a hang, so the wrapper doesn't need (and doesn't use) an externaltimeoutcommand, which macOS doesn't ship anyway. - A
review-pausedecision (sensitive or too ambiguous) never silently proceeds: an interactive terminal gets askedy/N(default no); a non-interactive one (a script, a pipe) refuses outright rather than run an unattended flagged task with nobody able to confirm it — the one branch that could not be tested against a fake TTY from this environment; it'll be exercised for real the first time it fires. - An explicit
--modelyou already passed is always honored, never overridden. - Every routing action prints a
[jclaude] ...line to stderr — nothing about this is silent.
A real bug was caught in testing, before this reached ~/.zshrc: the first version resolved
--project to basename "$PWD" computed inside the same subshell as cd "$jclaude_dir",
which put it after the cd — every task would have been logged under project barmajja-aios
regardless of which repo it actually came from. Fixed by capturing the project name before the
cd. Re-tested from a second directory to confirm the fix.
Activation: one line was added to ~/.zshrc:
[ -f ~/Desktop/barmajja-aios/shell/claude-wrapper.zsh ] && source ~/Desktop/barmajja-aios/shell/claude-wrapper.zshGuarded so a missing/moved/deleted repo just silently doesn't define the function — claude
falls back to the real PATH binary automatically, not an error. Takes effect in new terminal
sessions (a running shell keeps its old, unwrapped claude until restarted or the file is
re-sourced).
To remove: delete that line from ~/.zshrc (or delete shell/claude-wrapper.zsh), open a
new terminal. JCLAUDE_WRAPPER_DISABLE=1 in your environment disables it without editing
anything, if you just want it off temporarily.
Rollback
This is an entirely separate repo with no inbound references from any Barmajja repo. To remove
it: delete this repo, or just stop using it. Nothing in barmajja/barmajja or any other Barmajja
repo imports from it, references its path, or depends on it running — each of those repos only
carries a docs/jclaude-integration.md status note pointing here. The one exception is the
global wrapper above, which does reach outside this repo (into ~/.zshrc) by explicit request —
see its own section for how to remove that specifically.
History: why this repo exists now and didn't at first
The design brief (received 22 Sep 2026) called for this to live in its own repo from the start.
Creating a new repo under the Barmajja org via the GitHub App integration failed with 403
Resource not accessible by integration — the app was never granted the org-level
Administration permission that repo creation requires (a different, higher-privilege scope
than the "read/write code, branches, PRs" permission that let the same integration create
branches and push to existing repos without issue). That permission can't be added from the
org's app-installation settings page either — it's fixed by the app's own manifest, not a
per-org toggle.
Rather than stall, the build landed temporarily under tools/jclaude/ inside
barmajja/barmajja, following the precedent tools/review-bot/ already set there for
unrelated, never-shipped tooling. Once the repo owner created this repo manually on github.com,
its full contents were copied here unchanged (same commit history is not preserved — this is a
tree copy, not a git subtree/filter-repo migration — but every file, test, and the passing
test run are identical).
