RUL-027 — Production runs its own checkout, never the development tree
Ruling
Separate dev code from prod (user command, 2026-08-08).
Amended by ADR-0062 (2026-09-23, Proposed — rulings R1/R5): the path clause
changes from ~/prod/orchestrata-ultimate to /opt/orchestrata. ~/prod
never existed on this host; /opt/orchestrata is a mohamed-owned git checkout
reset --hard to the pinned sha by deploy/install-orchestrata.sh, with its
own .venv on python3.14t, VERSION promoted last, and an identity
verifier that refuses success unless the running units are that checkout.
Clauses 2–4 stand unchanged.
Concretely:
- Every production unit executes from
/opt/orchestrata(was~/prod/orchestrata-ultimatebefore ADR-0062), a dedicated git checkout that exists only to be deployed and is reset to a pinned ref by the installer. NoWorkingDirectory,ExecStart,EnvironmentFileorExecStartPreof any prod unit may reference~/workspace/orchestrata-ultimate-architectureor any/home/*/workspace/path. - The prod checkout owns its own
.venv— a real directory, never a symlink to the development virtualenv. This is RUL-021's rule applied to the deployment target rather than to a feature branch, and for the same reason: a shared environment means one tree'suv syncsilently changes another tree's runtime. - Deployment is an explicit checkout of a promoted commit, followed by a restart. Editing files and restarting is not a deployment.
- The development tree is never a deployment target. Nothing running there
is production, regardless of
ORCHESTRATA_ENV_PROFILE.
Why
Before this ruling all six prod units carried
WorkingDirectory=/home/mohamed/workspace/orchestrata-ultimate-architecture
and Environment=ORCHESTRATA_ENV_PROFILE=prod. Production executed the same
files an agent or a human was mid-edit in. Three consequences, all real:
- Every edit was a pending prod deploy. A half-written module became production code at the next restart — no promotion, no gate, no review.
git checkoutmoved production. Switching branches in the dev tree changed what prod would run, silently.- It made autonomous work unsafe by construction. The dogfooding plan
(
plans/dogfood-build-to-promotion.md) has agents editing this checkout; with prod bound to it, an agent could not touch a file without touching production.
The related 2026-08-05 incident is the same class one layer down: fleet probes
silently hit the PROD kernel on localhost:50053 because shells lacked the
profile overlay, producing a phantom P1 and two phantom transport bugs and
burning hours. Ambiguity about which tree and which endpoint is "prod" has
already cost real time twice.
Enforcement
- gate scripts/check_prod_tree_separation.py find_violations
Second mechanism per ADR-0062: scripts/verify_deployment_identity.py (with
src/orchestrata_ultimate/promotion/identity.py) proves identity, not health —
git -C /opt/orchestrata rev-parse HEAD == VERSION.commit == the expected
sha, every orchestrata-*/orchgraph-* unit's process has cwd, cmdline[0]
and exe under /opt/orchestrata, and no unit path directive references
/home/*/workspace/. It is called by deploy/ship.sh §5, by
stages.verify() (FAIL → rollback) and by install-orchestrata.sh --verify.
It is listed as prose, not as a gate bullet, until the script lands on
master: rulings_lint.py refuses a gate directive whose script does not
exist, and that refusal is the point (RUL-014). Promote it to
- gate scripts/verify_deployment_identity.py <rule-id> in the commit that
adds the script.
Mechanism (RUL-014)
That heading must read exactly ## Enforcement with directive bullets under
it: rulings_lint.py parses that heading and no other, so a section named
## Mechanism registers as NO declared mechanism at all. This ruling shipped
that way and the lint caught it —
RUL-027: '': no '## Enforcement' section / no bullets found
which is RUL-014's gate working, on the ruling that introduced it.
The mechanism itself is scripts/check_prod_tree_separation.py, wired into
scripts/gates.py as the prod-separation gate. It fails when any
orchestrata-* user unit references the development tree in a path-bearing
directive, and reports the offending unit and line. Prose alone would not have
caught the drift that created this ruling.
Related
- ADR-0062 — Production runs from a pinned-ref git checkout under
/opt/orchestrata(amends clause 1 of this ruling; Proposed 2026-09-23;docs/adr/0062-prod-is-a-pinned-checkout-under-opt-orchestrata.md) - [[RUL-021]] — every feature-branch worktree owns a full environment
- [[RUL-012]] — done means wired AND deployed
plans/dogfood-build-to-promotion.md§5 risk 1