Orchestrata Ultimate › Gates › codetools-gates

Gate: codetools-gates

At a glance

Purpose Prove a codetools master commit once per batch (install, verify, promote) inside a provisioned container, under a 300 s target, with the scope chosen by selection rather than the full suite.
Where it runs The codetools repo (/home/mohamed/workspace/orchestrata.codetools, src/codetools/gate/), deployed at /opt/codetools/bin/codetools. Designed to run from a systemd user timer codetools-gate.timer (src/codetools/gate/units.py).
Trigger The timer ticks OnBootSec=1min / OnUnitActiveSec=30s and runs codetools gate run --once; MasterWatch compares git rev-parse master with the sha of the last DONE batch record (master_watch.py docstring).
Exact commands codetools gate provision [--units] [--repo R] [--state S] · codetools gate readiness [--repo R] · codetools gate run --once [--repo R] [--state S] [--records D] [--ref REF] [--workers N] [--scope affected|full] [--reason TEXT] · codetools gate cpuset [--apply] [--repo R] · codetools gate status [--repo R] [--state S] [--records D] (all from --help, 2026-10-23).
Blocks A red probe is refusal class infra and nothing runs (readiness.py); a red batch is bisected over the merge list since the last green (batch_runner.py); an affected batch with no full verify record refuses naming the missing baseline (schedule.py).
Ruling / ADR codetools register (repo paths, not orchestrata's decisions page): docs/adr/0004, 0023, 0024, 0025, 0033, 0036, 0039, 0040, 0042, 0043 (Proposed), 0044. Orchestrata side: RUL-040, RUL-032.

These gates are separate from orchestrata-ultimate's own commit and push gates. They verify codetools, the deployed toolkit orchestrata consumes (codetools ast map for the codebase maps, codetools deploy select-affected for RUL-040's oracle seam). See codetools for the project itself.

Current state on this host (measured 2026-10-23, listing only)

So today the batch runner is designed, built and documented but not scheduled on this machine. Whether a batch has run since 2026-10-14 is not measured.

How a batch runs

From the module docstrings of batch_runner.py, schedule.py, readiness.py, cpuset.py and provisioner.py:

Diagram projects-orchestrata-ultimate-gates-codetools-gates-1

What each verb checks

gate provision

Idempotent provisioning of the installer container from env/contract.toml: "one step per contract item … nothing for what the contract does not declare. Every step probes first and acts only on the difference" (provisioner.py). It writes /opt/codetools-gate/PROVISION.json with the sha256 of the contract it satisfied. --units also installs the timer.

gate readiness

"The gate's readiness probes, run before ANY batch, derived from env/contract.toml — one probe per contract item, none that is not an item … the container must be RUNNING, its PROVISION.json must record the hash of THIS contract, and every item's probe must pass inside it" (readiness.py).

The contract (env/contract.toml, ADR-0039) declares 13 items today: batch-user (uid 1100, not root), locale (C.UTF-8), tool-uv, tool-python, tool-ruff, tool-git, tool-swipl, user-manager (a systemd --user for the gate user), basetemp-root, tmp-hygiene, endpoint-memgraph, capacity (performance_cores_unshared = 4, efficiency_cores = 4) and schedule (full_every_merges = 10). Each item's comment names the 2026-10-13 incident behind it: batch 1 ran as root with the C locale (410 s, 8 red tests), batch 2 found a stale /tmp trace file and no user manager (671 s, 10 red tests) — ADR-0039's context table.

gate cpuset

Derives the container's limits.cpu from the declared capacity and the sysfs topology: performance cores first, one thread per physical core so no worker shares a core, then efficiency cores; workers equals the unshared performance cores (cpuset.py, ADR-0040 rule 3). ADR-0040 records why: on the i7-1260P the container's "12 CPUs" were about 3 performance and 7 efficiency cores, and the same suite cost 4,355–4,830 CPU-seconds inside against 2,155 on the host. --apply sets it.

gate run --once

One batch, as in the diagram. Scope rules:

gate status

Prints the last batch record.

Gate What it does Source
codetools deploy select-affected "bound a changed-file set to a measured selection from a facts document on stdin (RUL-040 fail-closed JSON contract)": exit 0 bounded, 2 named refusal, 1 tool error; "never a bare full run" codetools deploy --help; commit 8f82f29f (2026-10-20). Orchestrata's P-RUL040 Stage 0 adjudication e7570a88d chose it as the seam; whether orchestrata's run_tests.py --affected calls it today is not measured.
Review gate (inside deploy install verify) Runs the ruff pinned beside the interpreter before PATH's, so a hook or unit with a bare PATH still finds ruff==0.15.12 commit 129d419f (2026-10-22)
Live-systemd lock Serialises every test that drives the real systemd --user; ADR-0033 narrows it to each live call commit b52409af (2026-10-13), docs/adr/0033-*
ct-install post-promote checks After codetools deploy install … --no-verify, runs codetools deploy verify-identity --prefix /opt/codetools --expect-commit <sha> and ~/bin/ct-smoke <sha> (version names the commit; ast map maps a 3-symbol repo with class Child(Base); mcp list has the ast map tool). Either failing runs codetools deploy rollback and exits 12. ~/bin/ct-install lines 50–66, ~/bin/ct-smoke

The ct-install path is the "Hermes model" Mohamed asked for on 2026-10-22 ("make the installer like hermes"): no suite gate at deploy time, proof through the installed command instead. The suite-gated verify stays available by running codetools deploy install by hand (~/bin/ct-install header, lines 43–49).

Prolog as the decision layer

ADR-0004 (Accepted, 2026-09-24): "the gates including the blast radius logic … designed, built and run in prolog". ADR-0023 (Proposed, amended): every deterministic gate's decision is a Prolog rule set; "Python atoms gather the data for speed, Prolog decides"; every gate verb supports --explain.

Typical failures and how to fix them

Symptom Cause (source) Fix
Batch refused infra naming an item A contract probe failed inside the container, or PROVISION.json records a different contract hash (readiness.py) codetools gate provision, then codetools gate readiness
affected batch refuses with a missing baseline No full verify record with coverage contexts on this executor (schedule.py, ADR-0042 rule 4) ADR-0024's one bootstrap run per executor, recorded as the first baseline; never a silent full run
Thermal refusal Capacity/thermal state outside the declaration (REQ-012-049 in batch_runner.py; ADR-0040 measured a 96 °C package, ADR-0043 a 100 °C package at a 394 MHz clock floor) Wait, or run on an executor that meets ADR-0040 rule 4
Batch exits coalesced Another batch holds the lock (ADR-0036 rule 2) Nothing: the merge joins the next batch
ct-install INSTALL-EXIT 12 and ROLLED-BACK verify-identity or ct-smoke failed after promote (~/bin/ct-install) Read the log in reports/ct8-install<label>.log; fix and re-run with a new label
Install refused at verify on PYTHONPATH The Claude settings env exports PYTHONPATH=/opt/orchestrata-tools/shim, which codetools' import-shadow guard refuses (install 68, commit 6979a4ad) ct-install now unsets PYTHONPATH PYTEST_ADDOPTS; do the same for any hand run