Orchestrata Ultimate › Plans › promotion-and-deployment-plan
Promotion to test + deployment — session 262 work
Source: plans/promotion-and-deployment-plan.md at 8a2cb42ad · last changed 2026-08-12 · first committed 2026-08-12 · 200 lines.
Prose pending.
Plan text
Promotion to test + deployment — session 262 work
Authored 2026-08-12. Covers everything fixed this session plus the five open items, through documentation, review, commit, promotion and deployment verification. Every number here was measured, not estimated; where a number is unknown the step says so and names the command that produces it.
Why the order is forced
Two rules pin the sequence, so this is not a preference:
- RUL-008 — the review battery runs before ANY commit, and every bug it
finds gets fixed regardless of scope.
scripts/gates.py --allis currently rc=1 (parallel-safety, 130 violations). So the triage gates the commit. - Promotion requires committed code.
scripts/promote_env.py testruns the suite pinned to an env;promote --to testadvances, restarts and verifies a deployment. Neither is meaningful against 97 uncommitted files.
A third constraint shapes where the work happens: RUL-023's wiring gate
SKIPs with "no diff against master", so work sitting uncommitted on master
produces a green that is absence of evidence. Doing this on a branch makes that
gate produce real evidence for the first time in this session.
Phase 0 — Branch and baseline
| # | Step | Verification |
|---|---|---|
| 0.1 | Create feat/session-262-gate-and-provenance off current master |
git branch --show-current |
| 0.2 | Record the pre-work baseline: gate counts, battery rc, suite totals | committed to reports/ as a baseline artifact |
| 0.3 | Provision the branch's env per RUL-021 (scripts/provision_worktree_env.py) — no symlinked .venv, no exported PYTHONPATH |
scripts/check_source_provenance.py |
Baseline to capture before anything changes (so every later claim has a
denominator): gates.py --all rc + per-gate lines; gate 0.4 count; the observed
suite totals; git diff --stat.
Phase 1 — Close the five open items
These are independent and run in parallel except where noted.
1.1 Triage the 130 parallel-safety violations — the critical path
Measured shape: 130 violations / 51 files. Groups (from the tree-wide
measurement): (a) 12 hardcoded global key literals in 4 files; (b) 91 keys from
non-test-scoped expressions; (c) 70 destructive verbs the old detector never
knew (delete 51, hdel 11, srem 7, lrem 1); (d) 75 receivers the old
regex could not match.
Exposure that makes this real: tests/conftest.py::redis_client passes no
db=, so it lands on shared db0 — where the live kernel and gateway run —
and its teardown reclaims only {test_id}:*.
Disposition rule, per site, no third option:
- the key becomes
test_id-derived (preferred — it is the actual fix), OR - a
# gate-ok: <reason>waiver stating why the site is safe on the merits (core/gate_waivers.py; a bare marker does not waive).
"It uses a per-worker DB" is a valid waiver reason and several sites qualify
(db=_worker_redis_db()); it must be stated, not assumed.
Sharded by file cluster so shards never touch the same file. Each shard proves its own work: the sites it owns disappear from the gate output, and its modules pass observed.
1.2 Gate 0.4 — the unsound exemption (BLOCKER, latent)
_resolve_module_calls (gate_parallel_safety.py:606) accumulates
next_seeds[func] across all call sites into one per-function set, so one
call passing a test_id-derived key retroactively exempts every other call
site of that helper — including one passing a hardcoded global key. Isolated
with a two-file control: byte-identical hazard, FLAGGED alone, NOT FLAGGED once
an unrelated scoped caller exists in the module.
Same defect class as the ±13-line window it replaced: an exemption that fires
without proving anything about the site it exempts. Armed but not live — 8
helpers in tests/ already have mixed derivation, none currently containing a
write verb.
Fix: make seeding per-call-site, not per-function. Red-first against the existing two-file control.
Majors to close in the same pass (each narrows what the gate sees):
- flow-insensitive scope — a later rebinding exempts an earlier write
- alias tracking misses
with redis_client.pipeline() as p: _is_testid_derivedtreats a Call as derived if any argument isgetattr/ lambda writes invisible;match/casebodies not walked
1.3 Worktrees — 2.0 GB, and a banned-dependency re-entry path
Four abandoned worktrees, zero live processes, all four carry the banned library import and dependency, so merging any of them reintroduces what this session removed. Three hold unmerged commits that are real work:
| branch | commit | content |
|---|---|---|
agent-a19bd3f45a6c20c7d |
79917186 |
share ToolSearchTool.create() across test_search fixtures |
agent-a90e6c1fb767671db |
705a46e7 |
trace_intel cold-KB build once per module, not twice |
agent-aad6ad8280c27cf26 |
e83fe602 |
one AST daemon per run instead of per-batch re-warm |
Per branch: review → strip the banned dependency → verify green on this branch →
cherry-pick or abandon explicitly → git worktree remove + branch delete.
Dirty files in them are regenerated plans/ast-*.json / reports/*.json which
stay out per the K3 artifact ruling.
1.4 test-purity gate scope
scripts/gates.py invokes audit_test_purity.py with no path argument, so
the new banned-import check covers tests/ only. A reintroduced banned import
under src/ or scripts/ is outside the gate entirely. Extend the invocation
and prove it with a red-first probe in each root.
1.5 Stale docstrings describing deleted behaviour
Three texts still say PipelineEventBus.emit "stamps driver on events" — the
mutation that was deleted. tests/kernel/test_pipeline_events_enum.py:144,185
and tests/kernel/test_pipeline_event_forwarder.py (~L140). A docstring that
describes behaviour the code no longer has is how the next reader re-adds it.
Phase 2 — Bug investigation sweep
Not "fix what we know" — hunt for what the same defect class implies elsewhere. Every defect this session shared one shape: a checker that cannot distinguish "nothing wrong" from "didn't look."
Confirmed instances: the codebase-map generator wrote 452 bytes of headers and
reported success; the purity audit whitelisted the import it existed to catch;
gate 0.4 excused three global keys because its regex matched a substring of the
test's own function name; a before/after measurement reported a confident zero
because the module resolved its scan root from __file__ in /tmp.
Sweep every gate and checker in scripts/ for the same shape, specifically:
- a scan root or file list derived from
__file__/ cwd that can silently be empty - an exclusion list that could exempt the thing the checker exists to catch
- a
|| true/ bareexceptthat converts failure into a pass - a "0 findings" that is not distinguished from "0 files scanned"
Each finding gets a red-first proof and a fix, or a written argument that it is unreachable.
Phase 3 — Documentation, specs, wiki
Nothing here is optional; RUL-012 puts documentation inside the definition of done.
| Target | Change |
|---|---|
specs/001-kernel/pipeline-event-type-addendum.md |
the driver field: producer-owned attribution, "" = unattributed and why that sentinel is load-bearing, the resolve-not-mutate contract, the two production producers and the structural guard that discovers a third |
| Spec for parallel-safety | gate 0.4's contract: what it flags, the two dispositions, and the exemption's soundness requirement (per-call-site, not per-function) |
AGENTS.md / CLAUDE.md |
the shared-db0 exposure and the test_id-derived-key requirement, if not already stated in enforceable terms |
docs/development-and-testing.md |
how to read a gate 0.4 violation and the two ways to resolve it |
.claude/rulings/ |
RUL-014 requires every ruling resolve to a mechanism — the banned-library ruling now has one (banned_import), record it |
Wiki projects/orchestrata-ultimate/ |
new page: the artifact-vs-description defect class, with all four measured instances; update pipeline-event-convergence.md (driver field + the un-forked golden), running-the-test-suite.md and suite-parallelism-floor.md (the 130 and shared db0) |
Wiki work follows the standing workflow: write the file, wiki create/update,
validate, re-index (wiki-rag-ingest).
Phase 4 — Review battery and commit
scripts/gates.py --all→ rc must be 0, withwiringproducing real evidence this time (there is now a diff against master).scripts/gate.py run→ PASS, not INVALID (a stale fact base is not a pass).- Full observed suite,
scripts/run_tests.py— the kernel is REQUIRED; a run that does not start and gRPC-verify it is invalid/false-green. - Code + test + architecture review per RUL-008; fix everything found.
- Commit in reviewable series by concern, not one omnibus commit. No AI attribution.
Phase 5 — Promotion to test
| # | Step | Gate |
|---|---|---|
| 5.1 | promote_env.py validate --to test |
profile + infra reachability |
| 5.2 | promote_env.py test |
full suite pinned to env/test.env, prod-subnet guard active |
| 5.3 | promote_env.py promote --to test |
advance + restart + verify |
| 5.4 | Redeploy the containerized test kernel + gateway in the app container (10.93.53.13) via deploy/orchestrata-test/provision_app_container.sh |
units healthy |
| 5.5 | promote_env.py status |
ledger records the promotion |
Prod is explicitly out of scope. promote --to prod is gated on a green
test-env run and is the user's decision, not this plan's.
Phase 6 — Deployment verification
Claims are only made about what was verified this session (RUL-012):
- kernel gRPC reachable at
10.93.53.13:50053; gateway WS at:8765 - both producers emit attributed events through the deployed kernel, read back off the wire
orchestrata watch --thread <id>renders backlog then live against the deployed gateway- gate 0.4 is 0 on the deployed branch
- the promotion ledger (
reports/promotion-state.json) carries a real timestamp
Definition of done
gates.py --allrc=0 includingwiringwith a real diff- gate 0.4 count 0, every site either
test_id-derived or waived with a reason - full observed suite green with the kernel started and gRPC-verified
- specs, docs and wiki updated and indexed
- session records the work, artifacts, choices and handoff
- test-env deployment verified live
- nothing about prod claimed