Orchestrata Ultimate › Plans › briefs › 2026-09-22-rul-032-run-once-ledger
Brief: enforce RUL-032 — a test module runs once per code state
Source: plans/briefs/2026-09-22-rul-032-run-once-ledger.md at 8a2cb42ad · last changed 2026-09-22 · first committed 2026-09-22 · 138 lines.
Prose pending.
Plan text
Brief: enforce RUL-032 — a test module runs once per code state
Ruling (Mohamed, 2026-09-22, verbatim): "with the rule enforced that test
only run once unless the code in the test or code is changed, and watch for
escalation to full suite when the tests have already been run, this should
never happen." Recorded as knowledge-wiki rulings/RUL-032-tests-run-once-per-code-state.md.
GOAL
scripts/run_tests.py never schedules a test module whose content key
matches its last green run, and scripts/affected_tests.py never escalates
to the full suite because an env/*.env file changed.
FACTS (measured 2026-09-22)
- Last verified base
66f18509d;affected_tests.py --since 66f18509dreturns escalate=True (reasons: env/test.env, env/dev.env, root conftest module-level change), 1008 tests, 12 untested. reports/run-tests-latest.jsonholds a scoped green run at HEADa9554e88…for 197 modules (tests/gateway, tests/kernel, tests/cxp, tests/test_gateway.py, tests/test_kernel.py, tests/test_cxp.py): 3977 passed.module_test_countsin that file gives per-module counts._try_reuse_reportreuses a whole report only when HEAD+dirty_sig match; it is report-level, not module-level. Keep it; the ledger is finer.- The serialized AST files the selector already loads (
_load_ast,build_test_import_map,build_reverse_dep_graph,build_module_file_map) give the test→src import closure. Reuse them; do not write a second import walker.
FILES
scripts/test_green_ledger.py(new)scripts/run_tests.pyscripts/affected_tests.py.gitignore(addreports/test-green-ledger.json)tests/scripts/test_test_green_ledger.py(new)tests/scripts/test_run_tests.pytests/scripts/test_affected_tests.py- Nothing else. Two other builders are editing
tests/semantic_graph/test_memgraph_ha.py,env/*.env, and the ADR tooling (knowledge_graph/adr_parser.py,architecture_writer.py,sync_architecture_to_graph.py,check_adr_graph_sync.py); do not touch those.
DESIGN (settled)
scripts/test_green_ledger.pymodule_key(test_path, *, repo_root, closure) -> str: sha256 over, in this order, the bytes of: the test module; eachsrc/file in its transitive import closure (sorted by path); eachconftest.pyfrom repo root to the module's directory;pyproject.toml. Env files are NOT inputs (ruling). Missing closure files are skipped, never fatal.closure_for(test_path)built from the selector's maps (forward closure of the test'sorchestrata_ultimate.*imports through the src dependency graph, bounded by the selector'sMAX_DEPTH).- Ledger at
reports/test-green-ledger.json:{module: {"key": str, "passed": int, "run_id": str, "head_commit": str, "ts": float}}, written atomically (tmp +os.replace). load_ledger(),record_green(modules_with_counts, run_id, head),partition(modules) -> (to_run, reused)where reused maps module → recorded entry.- CLI:
--status <paths…>prints per-module run/reuse;--seed-from reports/run-tests-latest.jsonrecords the report's modules as green ONLY when the report'shead_commitis an ancestor of HEAD andgit diff <head_commit>..HEAD --name-onlytouches none of that module's key inputs; modules that fail that check are listed and skipped. - The module docstring names
RUL-032(the rulings lint checks the rule-id appears in each declared gate script).
scripts/run_tests.py- In
_main, after affected resolution and the report-reuse check and before_run_suite: unless--force,partition(modules); print[run_tests] ♻ RUL-032: N module(s) unchanged since their last green run — reused, not re-run; M to run. If M == 0, do not start the executor: build the result from the reused entries alone (passed = sum of recorded counts, failed 0) and write the canonical report as usual. - The report gains
"reused": {"modules": N, "tests": n};test_totals.passedincludes the reused tests soship_already_verifiedand_try_reuse_reportkeep working unchanged. - After a green batch/solo round,
record_greenfor every module that passed, with its per-module passed count and this run'sORCH_RUN_ID/ HEAD. - Escalation path: when
--affectedescalates, the full module list is still passed throughpartition, so an escalation over proven modules runs only the changed ones. Print the reused count on that path too. - The docstring names
RUL-032.
- In
scripts/affected_tests.py_is_env_endpoint_configfiles no longer setescalate. Instead: diff the env file againstbase_rev(_diff_changed_linesexists), extract the changedKEY=names, and resolve each key to every test module andsrc/module whose text contains the key name (walktests/**/*.pyandsrc/**/*.pyonce; src hits resolve to their dependent tests via the existing reverse-dep + test-import maps). Reason text:env/test.env: keys A, B changed — resolved to <n> tests that name them (RUL-032: no escalation). A key nothing names resolves to the smoke floor only and is reported.
- Tests (real files, tmp git repos where the existing tests already do
that; no mocks):
- ledger: key changes when the test file, a closure src file, a conftest
or pyproject changes; key is unchanged when an env file changes;
partitionreuses only on exact key match; seed refuses a module whose inputs changed after the recorded head. - run_tests: a second invocation on the same tree schedules 0 modules
and reports
reused;--forceschedules all. - affected_tests: an env file edit that changes
TEST_MEMGRAPH_HA_MAIN_URIyields escalate=False and selects the modules naming that key.
- ledger: key changes when the test file, a closure src file, a conftest
or pyproject changes; key is unchanged when an env file changes;
CONSTRAINTS
- No mocks/fakes/stubs/monkeypatch, no skip, no xfail.
- Read Python through
scripts/serialize_codebase_ast.pyonly; edit with Edit/Write. Test runs: background,timeout 300,ORCHESTRATA_ENV_PROFILE=test,-p orchestrata_ultimate.core.threading.pytest_live_observer. - Do not run the full suite. Do not run
ship. - Commit with
git -c user.name=Mohamed -c user.email=msamy@sufigeeks.org, no AI attribution (RUL-007). Do not push.
DONE WHEN
tests/scripts/test_test_green_ledger.py,tests/scripts/test_run_tests.py,tests/scripts/test_affected_tests.pypass in one observed background run (0 failed / 0 skipped / 0 xfailed).uv run ruff check,uv run black --checkanduv run pyrightclean on the touched files (this repo formats with black).uv run python scripts/rulings_lint.pypasses with RUL-032's two gate lines resolving (the wiki file is already in place).uv run python scripts/test_green_ledger.py --seed-from reports/run-tests-latest.jsonseeds the 197 modules (or lists exactly which were refused and why).uv run python scripts/affected_tests.py --since 66f18509d --jsonreportsescalatefalse for the env files (the root-conftest reason may remain; report it verbatim).- One commit on master with the seven files and this brief unchanged.
VERIFY (report verbatim)
- The pytest summary line.
- The rulings_lint output lines for RUL-032.
- The
--seed-fromoutput. - The
escalatevalue and the env-related reasons from the selector run. git show --stat HEAD.