Orchestrata Ultimate › Plans › spec-110-completion-plan

SPEC-110 completion plan — build what the spec still owes

Source: plans/spec-110-completion-plan.md at 8a2cb42ad · last changed 2026-10-07 · first committed 2026-10-06 · 880 lines.

Prose pending.

Plan text

SPEC-110 completion plan — build what the spec still owes

Directive: Mohamed, 2026-10-06: "build spec 110". Worktree: wt-SPEC-110 (feat/spec-110-completion, base origin/master 83c604886). Authority: specs/110-codemod-engine/spec.md (51 REQ ids) + the ctok-parser contract (plans/contracts/ctok-parser.*, REQ-110-120..127). RUL-013: tests cite only ids the spec defines.

0. Measured state (2026-10-06, in this worktree)

Source of truth for "done": specs/110-codemod-engine/checklists/requirements.md (last reconciled 2026-08-13) cross-checked against the tree today.

Requirement Checklist says Measured today Verdict
REQ-110-001..024, 026, 028..030 COMPLETE @traces present in refactor/codemod/; tests in tests/refactor/codemod/ done
REQ-110-025 NOT WIRED workspace.run()/commit() construct no CodemodEvent, compose no SyncObservable (`grep -rn "CodemodEvent(" src scripts grep -v observability/→ 0 hits, asplans/codemod-observability-wiring-design.md` §1 measured)
REQ-110-027 NOT IMPLEMENTED neither method accepts observers= open
REQ-110-031 NOT IMPLEMENTED none of BlastRadiusAnalyzer, BreakingChangeDetector, ComplexityAnalyzer, TestCoverageMapper, AbstractionAnalyzer, CouplingAnalyzer, DeadCodeDetector exist; the computations exist only as CodeIntelligenceGraph query methods open
REQ-110-032 NOT IMPLEMENTED depends on 031 open
REQ-110-033 NOT IMPLEMENTED review.py ships 4 passes (ParseIntegrity, BannedConstructs, DiffBudget, PrologSemanticReview), no InMemoryReviewEngine, no 40-check catalogue open
REQ-110-034 NOT IMPLEMENTED, stale says "LibCST trees / CSTTransformer/CSTVisitor"; LibCST is GONE from the tree (0 hits in pyproject.toml and uv.lock, 0 imports under src/+scripts/) since the ctok migration (REQ-110-107 superseded, REQ-110-120..127). Unmeetable as worded open — needs a ruling (ADR-0068)
REQ-110-035 NOT IMPLEMENTED no three-phase engine open
REQ-110-101..106, 108 COMPLETE gates/coverage conventions hold on master done
REQ-110-107 superseded by REQ-110-120..126 closed
REQ-110-133..139 COMPLETE daemon/server/client/watcher carry @traces done (P4 of ADR-0067 is moving start/stop/status onto systemd in wt-AST-DAEMON-P4; not this plan's scope)
REQ-110-140 COMPLETE [x] FALSE. scripts/codemod.py parses --auto-start and --no-daemon and never reads either; it never constructs CodemodClient; no "auto-connect", no library-mode warning. Found by the P4 reviewer 2026-10-06 (design note 9), confirmed here by refs CodemodClient (test-only users) open — checklist is wrong
REQ-110-120..127 COMPLETE ctok layer present done

Spec-cited ids with no citation anywhere in code/tests: 006, 011 (behaviour exists, @traces cites neighbours — a traceability gap, not a feature gap), 031..035, 101..106, 108 (non-functional; cited by gates, not decorators). Code cites ids the spec does not define: REQ-110-050, REQ-110-085 (RUL-013 violation candidates — audit in S5).

Definition-of-Done items (spec §17) already on disk: contracts plans/contracts/spec-110-codemod-engine.{mmd,contract.json}, src/orchestrata_ultimate/prolog/codemod_review.pl, briefs plans/codemod-engine-briefs/, the C extension, 16 feature files. The contract diagram has NO class for the analysis passes or the review engine — RUL-022 requires that before S2/S3 build.

1. Decisions

2. Packets

Packet Scope Design authority Status
S1 REQ-110-025/027 — compose SyncObservable[CodemodEvent] in CodemodWorkspace, emit the 13 event kinds from run()/commit(), observers= parameter, default observer set plans/codemod-observability-wiring-design.md + plans/contracts/spec-110-codemod-engine.contract.json (reused_infrastructure: SyncObservable) ready
S2 REQ-110-031/032 — seven analysis-pass classes in the refactor/codemod/analysis/ package (one submodule each), read-only, dataclass results, scripts/codemod.py analyze surfaces them contract extension committed 9f7ee385d (plans/contracts/spec-110-codemod-engine.{mmd,contract.json} FR-011 classes, analysis_cig_mapping, analysis_gaps, TST-110-015..020, DOD-S2-1..5) built 2026-10-06 (code 2759b2857 on feat/spec-110-completion); reviewer GO at round 3 (3e4fe1e6d) after two fix rounds; SHIPPED 2026-10-06, master d23993eaa then bfe6f0943 (ship attempt 3), all three deploy targets verified; prod promote RAN and FAILED at verify on the pre-existing consumer R16b fault, rolled back to 287826a9 (ship-log row below)
S3 REQ-110-033/034/035 — InMemoryReviewEngine, 40 checks in 7 categories, three phases over the mutated forest, in new modules review_engine.py / review_catalogue.py / review_checks.py ADR-0068 (Accepted 2026-10-06) + contract extension 9f7ee385d (FR-012 classes, check_catalogue 40 ids, s2_s3_wiring, TST-110-021..026, DOD-S3-1..5) built 2026-10-06 (code 24b856ccd on feat/spec-110-completion; docs, checklist and contract D27 in the next commit); seven review rounds 2026-10-06/07, last fix c6946173a (round 7, full codemod suite 1,069 / 0 / 0); ADR-0073 Accepted and executed; ship-prep 16edf7c68 (D28, ADR Provenance, AST snapshot) and 48952a12a (verified RTM); shipping via deploy/ship.sh 2026-10-07, result in the ship log row
S4 REQ-110-140 — --auto-start/auto-connect/library-mode warning in scripts/codemod.py through CodemodClient spec §11.2 after P4 merges
S5 checklist/trace hygiene: flip REQ-110-140 to [ ] with the measurement above (then back when S4 lands); @traces for REQ-110-006/011; audit REQ-110-050/085 against RUL-013 — with S1

S5 findings (S1 reviewer round 1, 2026-10-06). REQ-110-006 was marked [x] in the checklist with no implementation: refs _update_index and symbols --pattern update_index return nothing, and after AddImportPass rewrote a file the workspace dependency index did not change (reviewer probe probe_index.py). The row is now [ ] NOT IMPLEMENTED and the checklist totals read 43 COMPLETE / 1 superseded / 7 NOT IMPLEMENTED. Owed: an incremental _update_index(paths) on CodemodWorkspace that run() calls for the mutated paths (with @traces for REQ-110-006), then flip the row back. REQ-110-127 is cited by passes.py and is NOT in spec.md, but IS defined in the checklist's FR-CTOK section (the ctok-parser contract, ids 120..127; the text matches RenameSymbolPass's edit-safety guard), so those citations stand; whether spec.md absorbs 120..127 is an ADR matter for the S5 audit.

S4 measured state (orchestrator, 2026-10-07, at f21ab3af8; P4 has landed so D4's sequencing condition is met). REQ-110-140 is partly built and partly contradicted: (S4-a) scripts/codemod.py main() (:791-813) runs _auto_start_daemon when --auto-start is given and --no-daemon is not (P4, ADR-0067: the deployed unit orchestrata-codemod-daemon@<escaped repo> is started through CodemodDaemon.start), but every command then loads the workspace locally anyway: _cmd_run (:344-414), _cmd_analyze (:696-788) and _cmd_load_bench all call CodemodWorkspace.load(root, …); nothing in the CLI imports CodemodClient, no socket is ever opened, and the library-mode warning REQ-110-140 requires does not exist. (S4-b) the daemon's commit RPC (server.py:_dispatch, branch method == "commit") ignores its changes parameter and commits ChangeSet(entries=()) — a daemon-side run --apply writes nothing (carried item C-c). (S4-c) CodemodWorkspace.run (workspace.py:560-614) replaces self._forest[path] with each mutated tree; commit(dry_run=True) restores nothing, so a pass run through the daemon leaves the daemon's live forest mutated for every later client until a disk change triggers a reload. (S4-d) the query RPCs return CIG node ids (query_dependencies, query_dependents, query_cycles, query_topological_order, query_centrality pairs), while the CLI prints cig.nodes[id].qualified_name; identical CLI output in daemon mode needs a name-resolution method the RPC surface does not have. REQ-110-138 lists the methods the daemon SHALL expose and the Python types; it does not describe the wire representation of a ChangeSet (parsed trees cannot cross a JSON socket). The S4 design (by-reference pending runs on the server, forest restore after a dry run, a node-resolution method, the CLI connection decision and warning text) is a RUL-022 contract entry (D29), not a spec amendment: no spec sentence is contradicted by it, and the methods REQ-110-138 names keep their names and Python-side types. S4 also owns C6 (_sweep_docstrings_and_comments rewrites every simple str/bytes ast.Constant; REQ-110-010 says "docstrings AND comments" — the docstring test is ast.get_docstring's: the first statement of a Module/ClassDef/FunctionDef/AsyncFunctionDef body being an Expr(Constant[str])) and C5 (_parse_string_token drops the r/b/u prefix on rewrite, so a raw docstring loses its prefix and its backslashes change meaning; and the implicit-concatenation span defect at passes.py:779, unreachable for docstrings once C6 restricts the sweep, is closed by a test that proves it).

S4 build (2026-10-07; contract D29 daec60c25; brief 293afd07b; builder commits 3880b35e9, a14be9051, 17178620f, 92f3e1881, 3a29ee3d0). Groups G1 91 / G2 105 / G3 77 / G4 162 passed, 0 failed, 0 skipped; coverage scripts/codemod.py 98%, server.py 99%, client.py 100%, passes.py 99%; ruff, black, pyright, check_spec_authority, gate.py run, check-deps clean. Both-modes equality proven for 13 analyze cases (rc, stdout, stderr identical), run dry and --apply (stdout minus Duration:/Commit report:, report payload minus durations/correlation id, files byte-identical), two stacked passes; forest unchanged after a daemon dry run, restored on disconnect, foreign run_id refused -32602. Sweep over src/orchestrata_ultimate/tools with {"timeout": "deadline"}: 7 files, 18 lines, 17 docstring + 1 comment, 0 code, ast.dump equal after emptying docstrings. Builder's judgment calls, recorded as D29 refinements: (1) the warning prints systemctl --user start <instance> where <instance> is CodemodDaemon._unit_instance(repo) (already the full unit@escaped.service); (2) the server resolves --module through resolve_node_id (the CLI's strategies: module:<path>, raw key, dotted) so both modes agree; (3) the forest is restored on dry run, on a refused review (success=False) and when ws.commit raises, not only on dry run; (4) one pending run per connection, reload refused -32602 while a run is pending (the write lock is non-reentrant); (5) run_pass also returns pass_name; CodemodRpcError(.code) replaces the bare RuntimeError in the client. S4 backlog: breaking_changes, complexity, test_coverage, dead_code, all-passes stay library mode with the notice codemod: '<query>' has no daemon method; parsed locally (breaking_changes needs a git-ref diff of the working tree, _changes_since, which no RPC serves). C7 — fixed in the S4 fix round (not carried): ReplaceStringLiteralPass drops the string prefix (b"", r"", u"", rb"") when it rewrites a literal, so a bytes literal becomes str and a raw literal's backslashes change meaning (the sweep had the same defect, C5a, fixed in 17178620f; both share _parse_string_token, now (prefix, quote, content), and the replace pass's call site still writes quote + new + quote). Rule: write prefix + quote + new + quote; a b/B prefix whose new value is not pure ASCII is left unchanged (a bytes literal cannot carry it) and the pass reports nothing for that literal; tests for b"x", r"x", u"x", rb"x" and the non-ASCII bytes case prove the bytes of the prefix survive. Hygiene: the header of tests/scripts/test_codemod_cli.py still lists "cycles can never materialize" and a _resolve_pass fallthrough as residuals; both are stale (the daemon fixture prints an alpha <-> beta cycle in both modes) — S5.

S4 review and fix rounds (2026-10-07; brief §§5–8). Reviewer round 1 NO-GO on 293afd07b..3a29ee3d0: one blocker (--include ignored in daemon mode — a daemon serving src, scripts, tests wrote 3 files where --include src wrote 1), one major (the inotify reload swapped the workspace outside the write lock), seven others (lease, commit error cause, --auto-start socket wait, C7, quote-char guard, docs). Fix round 1 (162145987, 2cfa5c2c5, 779766945, 6d2fea688): daemon mode only when the daemon's loaded roots equal the folded --include, else one notice and library mode for that run; replace_workspace under the write lock; pending-run lease 120 s with a bounded writer wait; commit failures -32000 <Exc>: <text> and Error: <text> rc 1 in both modes; --auto-start waits for the socket (CODEMOD_AUTO_START_WAIT, default 300 s). Fix round 2, the round-1 builder's own left-alone list (brief d9a5bf005; d67591e4c, 7a7fc6599, 83b01aed1, 3d96149d6): reload keeps include_roots/cache_dir; the quote guard refuses a raw newline into a non-triple literal; connect retries 3 × 50 ms across the bind/listen window; pyright narrowing in the CLI tests — G1 124 / G2 115 (+82 daemon-mode) / G4 198 passed. Confirmation review GO with six minors (probes rev2_cli.py, rev2_server.py, rev2_stale.py); fix round 3 (brief 8ff72592b; f8039d2da, fe68dbdd4, 8a44cdca9, dff2c63f6): commit_generation guard so a reload loaded before a commit is dropped (probe: disk NewWord, forest OldWord, dry run reported file_count 0); lease expiry re-checked under _pending_lock (20 same-instant commit/run_pass pairs: A committed then B ran, 20 of 20; pending_runs 0, forest == disk, no ConcurrentEditError); the shared literal guard finally runs ast.literal_eval (the five probe cases \N, \x, \u12, """C:\OldWord""", NUL leave the file unchanged, rc 0, both modes); bind/listen test margin ≥ 120 ms; --auto-start ends on a dead unit with daemon <instance> failed before serving (<state>); docs. Measured after round 3: G1 131 / G2 119 / G3 121 / G4 214 passed, 0 failed, 0 skipped; coverage server.py 98 %, passes.py 99 %, scripts/codemod.py 98 %; gate.py run PASS (421,978 facts), ruff, black, pyright, check_spec_authority, check-deps clean. The round-3 builder's one deviation — CodemodDaemon.start() waited the whole 10-s MainPID poll on a launcher that died at once — is fix round 4 (brief §8, 524b62fae; amendment 114be9ce4 after the wirer measured a second window: the first show after systemctl start still carries the dead launcher's MainPID), the RUL-024 disposition being FIX: start() settles 1 s (START_SETTLE_SECONDS) and raises the same failed before serving text when the unit leaves active. Round 4 landed as 12b5e8188 (wirer; second amendment e324c3849 added the H5 test's stale 1.0 <= elapsed lower bound to FILES): the new TestDaemonStart dying-launcher test 10 of 10 (2.0–2.8 s each), the H5 CLI test 5 of 5, lifecycle + daemon-coverage modules 65 passed, -k auto_start 9 passed, daemon.py 92 % (the deadline raise and the zero-MainPID raise are the uncovered branches: the measured window puts the dead launcher's pid in the first show, so the settle is the branch that fires), ruff/black clean. Failure text before <instance> reported no MainPID within 10s (ActiveState=<state>); after daemon <instance> failed before serving (<state>) at once, and … (no MainPID within 10s, ActiveState=<state>) at the deadline. Contract D29 carries all 21 S4 commits and refinements R1–R13.

S2 backlog (D9; owed CodeIntelligenceGraph work, S2 builder 2026-10-06). The S2 analyzers add no graph method; each reduced result below names the method the graph still owes. (1) GAP-1: reachable(roots, edge_types) plus a public edge-type accessor and an entry-root definition, so DeadCodeDetector can report symbol-level dead code (today granularity == "module", unreachable_symbols empty). (2) GAP-2: CALLS resolution by qualified name instead of the first node inserted under a callee name. (3) GAP-3: cross-file TESTED_BY resolution (test-module IMPORTS edge plus name match). Two defects found while building it: the builder writes TESTED_BY as function -> test (sink_edge_from_key) while CodeIntelligenceGraph.affected_tests reads edges INTO the function, so affected_tests returns nothing on a built graph (TestCoverageMapper._edge_tests reads both directions); and _visit_func types a callable Test only for methods under tests/ (and binds before or), so a top-level tests/test_x.py::test_foo stays Function (the mapper adds a path rule). (4) GAP-4: per-edge-type coupling and blast radius (IMPORTS only). (5) GAP-5: a signature diff inside breaking_changes (HAS_PARAMETER edges) with symbol-level consumers instead of module importers. (6) GAP-6: cyclomatic, nesting and cognitive complexity as graph queries. (7) New finding: CodemodWorkspace.load() collects files with an unsorted rglob, and the builder resolves an IMPORTS edge only to a module already registered, so the IMPORTS edges inside one directory depend on filesystem listing order (the S2 fixtures put importees in earlier include directories to stay deterministic). CLOSED in S2 fix round 1 (see the S2 review log): load() sorts the file list, the builder resolves IMPORTS in a second pass over the finished module table, and the dotted name is mapped through the include roots, packages and relative levels (the first S2 build resolved only 324 of the repo's IMPORTS edges, 2 of them into src/). (8) NOTE-1 (S2 fix round 2): a roots option for DeadCodeDetector that excludes tests/. 132 src/ modules are reachable only from tests on this repo (265 are unreachable with scripts-only roots), so with the shipped roots (every tests/ module is a root) the detector reports 0 unreachable and the option is the way to a useful production dead-code answer. No code change in S2. (9) Reviewer round 3 (GO) MINOR-A/B, resolver layout heuristic: _ImportResolver._roots_for bounds the root list only when the importer's package sits below a non-package directory (src layout); a package at the repo root (mypkg/__init__.py) falls back to every top-level directory, so mypkg/m.py: import utils binds tests/utils.py, and inside a repo-root package bare names try alphabetical top-level dirs before the importer's own (tests/test_x.py: import helpers binds scripts/helpers.py over tests/helpers.py). This repo is unaffected (src layout; edge set identical before/after, verified by the reviewer's full-repo identity run). Fix: for a repo-root package add only the importer's own top-level directory to [own_root, "", *pkg_roots], own directory first. (10) Reviewer round 3 NOTE: INHERITS = 0 and OVERRIDES = 0 over all 3,226 modules at both 4f31851c6 and HEAD — an unresolved edge kind that AbstractionAnalyzer/BreakingChangeDetector may depend on; audit item. (11) The loader reads gitignored paths (scripts/_janus_patched/build/lib* becomes an inferred package root and janus_swi binds its build artefact); exclude build//gitignored paths at load time. (12) test_node_ids_follow_sorted_file_order carries REQ-110-031 though it tests loader id ordering; retag when the loader REQ is settled. (13) Pre-ship verified RTM regen (2026-10-06, after the master merge): REQ-110-031/032 graded FAILING because tests/refactor/codemod/analysis/__init__.py cited both ids in its docstring; generate_rtm_evidence.py --verify runs pytest on every citing file, a package __init__ collects nothing (exit 5), and that FAIL outweighs the nine passing test modules. Fixed in this packet by dropping the ids from the __init__ docstring (a non-test file claims no requirement) and regenerating. The verifier behaviour itself (exit 5 on a non-test citing file graded as FAILING; tests/conftest.py has been in the FAIL list for the same reason since S1) is the S5 N4 "RTM false confidence" item: a citing file that collects no tests is a MALFORMED citation, not a failing one. (14) Prod identity drift measured 2026-10-06 after ship attempt 3's rollback: /opt/orchestrata/VERSION reads commit 7a5347cc… deployed 2026-09-23T18:14:11-04:00 while the tree HEAD is 287826a9 (the 2026-09-23 run-evidence commit). record_version captures the previous VERSION text and rollback restores it verbatim, so every failed promote re-asserts the stale file, and the identity verifier reads VERSION as "what is deployed". Owner: P6/PH1 with the consumer fix (ADR-0072); the next promote that reaches a green verify rewrites VERSION to its own sha and closes this. (15) S3 pre-ship verified RTM regen (2026-10-07, 48952a12a): REQ-110-033/034/035 graded TESTED; the 7 FAILING rows are not SPEC-110's and fall into two shapes of the same (13) verifier defect plus one doctrine violation. Shape A, marker-deselected modules: tests/e2e/test_full_pipeline.py and tests/orchestrator/test_pipeline_e2e_{analysis,docs_session,review}.py carry pytest.mark.llm_integration, which the default lane excludes by design (pyproject.toml markers), so the verifier collects nothing (exit 5) and grades REQ-003-FR24-100..103 FAILING, although they were never run. Shape B, non-test citing file: tests/conftest.py (REQ-008-006, REQ-021-069), as in (13). Doctrine violation: tests/knowledge_graph/test_context_pack_performance.py carries pytest.mark.skip and skipif (REQ-106-044), against the no-skip rule; owner SPEC-106. The grading fix (a deselected or non-test citing file is MALFORMED or UNVERIFIED, not FAILING) is the S5 N4 item; the skip removal is its own hygiene item.

Each packet: builder → reviewer → fix → bash deploy/ship.sh from this worktree (prod promote refusal stands until ADR-0067 P5; expected).

S1 review log.

Packet Definition of Done (ADR-0069 / RUL-034, Mohamed 2026-10-06: "do not forget annotations, rtm, documentation, wiki update and 90% code coverage" … "it should br the definition of done for all specs"). No packet is shipped until all five hold in the same ship: (1) @traces on every added/changed symbol and test, spec-defined ids only; (2) RTM regenerated (generate_rtm_evidence.py, trace_intel.py untraced-reqs before/after for SPEC-110); (3) checklist rows flipped in the code commit + docs/ and plans/ design status updated; (4) knowledge-wiki SPEC-110 page updated and shipped; (5) ≥90% line coverage per touched source file, measured. The S1 brief was amended in flight with these on 2026-10-06; S2–S5 briefs carry them from the start. The ship log below gains the five as columns.

S2 review log.

3. Ship log

Packet Date Master sha Suite Deployed Promote Traces RTM Docs Wiki Coverage
S1 2026-10-06 fba554e98 (26 commits fast-forwarded from 2893e2b6b; ship verify: affected suite from 207956a2 = 122 passed / 0 failed, 5 modules, 29 s; ruff, black, RUL-007, gen_plugin --check all clean) codemod suite + test_codemod_cli.py (excluding test_workspace_perf.py, test_benchmark_load.py, test_workspace_load.py::test_memory_guard): 822 passed / 0 skipped (fix round 5, a4bc5e436); reviewer round 6 on the four targeted modules: 165 passed / 0 skipped Claude config (VERSION fba554e9, 143 files match, hooks on the deployed venv), tools (VERSION fba554e98, codemod_fast + ctok rebuilt, both template units byte-identical to staged, systemd-analyze verify OK), gitlab-runner — all three verified at fba554e98 REFUSED — no GREEN test-env record (standing refusal since P1; P5 unblocks by retiring the two checkout-bound plain units that fail the prod identity verify) @traces on _Operation, run, commit, observable, subscribe, tests (REQ-110-025/027) reports/rtm-evidence.{json,md} regenerated with --verify --verify-timeout 600 on the final tree (b81a7f0bd, 2026-10-06, load 1.5 on 16 CPUs): 179 citing modules, 170 PASS / 9 FAIL; TESTED=329, FAILING=15, DECLARED=2975 (from TESTED=333 / FAILING=11 at 207956a2e). REQ-110-025, REQ-110-027, REQ-110-014..016 TESTED. The one grade change is REQ-110-133/134/135/137 → FAILING from tests/refactor/codemod/test_daemon_lifecycle.py::TestPidIsCodemodDaemon::test_a_daemon_for_a_different_repo_root_is_not_ours, which now fails solo at idle too (the predicate reads /proc/<pid>/cmdline before the child has populated it; test defect, P4 carry-over, P5 owner, in the P5 brief). The other eight red modules are the P4-classified set (tests/conftest.py harness artefact, exit 5; test_full_pipeline, three test_pipeline_e2e_* and test_context_pack_performance red on master too; test_workspace_load.py load-only; test_trace_intel.py worktree fact-base gap). A first regeneration with PYTHONPATH=scripts alone also flipped REQ-031-043: the qa volk's nested pytest in a tmp venv could not import orchestrata_pytest_observer once the session's /opt/orchestrata-tools/shim was dropped from PYTHONPATH; that run was discarded and redone with PYTHONPATH=scripts:/opt/orchestrata-tools/shim docs/codemod-observability.md, design §8, checklist rows 6/27/34/158/164 knowledge-wiki d5efcd2 (S1 summary) + 3043431 (shipped state: rounds 2–6, --observe, rollback semantics; pushed to origin/master, RAG re-indexed) (modules/refactor.md) Round 1: workspace.py 98%, txn.py 94%, passes.py 99%, events.py 100%, report.py 98% over tests/refactor/codemod/. Round 2 (measured 2026-10-06 over tests/refactor/codemod/ + tests/scripts/test_codemod_cli.py): scripts/codemod.py 96%, txn.py 94%, workspace.py 98%. Excluded from the coverage run: tests/refactor/codemod/test_workspace_perf.py (REQ-110-003 wall-clock parse bands over a stratified real-corpus projection) and tests/refactor/codemod/test_benchmark_load.py (serial-vs-parallel load timing benchmark). Reason: both assert wall-clock and RSS thresholds that coverage tracing inflates past the band, so under --cov they measure the tracer; both run in the default gate without --cov, and the load() lines they reach are covered by test_workspace_load.py. The round-2 coverage run had failures (review log N-d records two): test_workspace_load.py::test_memory_guard failed under --cov at RSS 3.7634 GB, about 5 MB over the 3.5 GiB = 3.7581 GB band (coverage tracing inflates RSS); the second was a tests/refactor/codemod/test_daemon_lifecycle.py argv probe (TestPidIsCodemodDaemon) that failed once under --cov while a different test in that module failed on the solo re-run (a /proc argv race right after Popen, not caused by this packet); the two affected modules pass in a no-coverage run (87 passed). Round 3 (measured 2026-10-06, 814 passed, 0 skipped, over tests/refactor/codemod/ + tests/scripts/test_codemod_cli.py, excluding test_workspace_perf.py, test_benchmark_load.py and test_workspace_load.py::test_memory_guard; the three excluded for the same tracer-inflation reason): scripts/codemod.py 96%, txn.py 93%, workspace.py 98%. Fix round 5 (measured 2026-10-06, same scope and exclusions, 822 passed, 0 skipped): txn.py 95%
S2 (build 2759b2857; fix round 1 f6a67f847; fix round 2 83e74cbad; round-3 GO record 575db493d; master merge 654c98704; init-citation fix bb48acb2d; RTM cb18b54eb) 2026-10-06 d23993eaa (16 commits fast-forwarded from 43f0dc043; the last is ship's own "record the authoritative run for 025e81016"). SHIP ATTEMPT 1 (025e81016): verify's --affected escalated to the FULL suite because the new analysis/ modules sit outside the serialized import closure; 38,229 passed / 3 failed / 0 skipped over 1,923 modules in 1,995 s on a contended box (load 5-7); the three failures are wall-clock assertions in modules S2 never touched (test_test_executor.py::TestRerunRoundSafetyNet ×2, test_knowledge_sync.py::TestEnsureFreshBudgets::test_ensure_fresh_stops_early_on_wall_clock_deadline); both classes 6 / 6 passed solo at idle (load 1.4); ship refused (rc 1), nothing pushed. SHIP ATTEMPT 2: RUL-032 reused 1,926 green modules, re-ran the 2: 38,232 passed / 0 failed / 0 skipped; ruff, black, RUL-007, gen_plugin --check clean; pushed; master fast-forwarded. This row's final cells are committed after the ship and land on master with the next one, as the P5 third-ship row did. POST-MERGE (origin/master 43f0dc043 merged at 654c98704, no conflicts; the P5 daemon.py / test_daemon_lifecycle.py changes included): tests/refactor/codemod/ + tests/scripts/test_codemod_cli.py + tests/scripts/test_codemod_fast.py in one process with the observer plugins = 967 passed / 0 failed / 0 skipped, plus one teardown ERROR from the git-sentinel in test_server_coverage.py that was the orchestrator's own plan commit (da0b92b09) moving the branch ref during the run, not a test writing to the repo; that module alone afterwards 14 passed. REVIEW ROUND 3 (GO against 3e4fe1e6d): 179 + 785 passed / 0 failed / 0 skipped; test_memory_guard 3,631 / 3,633 / 3,621 MB under the 3,758 MB band; IMPORTS edge set identical (7,927) before and after the resolver fix. FIX ROUND 2 (single process, plain, after 83e74cbad): analysis/ + test_cig_builder_ast.py + test_codemod_cli.py + test_workspace_load.py = 179 passed / 0 failed / 0 skipped, test_memory_guard included and green (HEAD after 3,645 MB mean n=4, 3,646 MB mean n=7, highest 3,688 MB, band 3,758 MB); the remaining tests/refactor/codemod/ + test_codemod_fast.py = 880 passed / 1 failed / 0 skipped, the failure being the known test_daemon_lifecycle.py::TestPidIsCodemodDaemon /proc argv race (P5 carry-over); gates after the round: gates.py ALL GATES PASS (exit 0, 19 gates), gate.py run exit 0 immediately after, check-deps --include-tests 0, check_spec_authority.py 0. FIX ROUND 1 (single process, plain): tests/refactor/codemod/ + tests/scripts/test_codemod_cli.py = 921 passed / 2 failed / 0 skipped; the 2 failures are pre-existing and unrelated to the fix (test_daemon_lifecycle.py::TestPidIsCodemodDaemon::test_a_daemon_for_a_different_repo_root_is_not_ours is the FAILING row in the S1-verified RTM; test_workspace_load.py::test_memory_guard fails on cae1f22a4 too, 3,766,550,528 B vs the 3,758,096,384 B band, and at 3,833,843,712 B with the fix, one sample each); the other 921 pass (the 52-test CLI file is among them); gates after the fix: gates.py ALL GATES PASS (exit 0, 19 gates incl. ruff and mypy), gate.py run exit 0 run immediately after gates.py (no ast-sync needed), check-deps --include-tests 0, check_spec_authority.py 0. Before the fix round: 94 passed / 0 skipped (builder run, single process); gates.py ALL GATES PASS (19 gates, ruff, mypy), gate.py run exit 0, check-deps --include-tests exit 0, check_spec_authority.py exit 0 Claude config (VERSION d23993ea, 143 deployed files match, plugin 214 files at d23993ea, hooks on the deployed venv), tools (VERSION d23993ea, staged record d23993eaa, entry points and observer plugin resolve under /opt/orchestrata-tools, deployed venv 3.14.7 free-threaded), gitlab-runner (DEPLOYED d23993eaa, unit active) — all three verified at d23993eaa RAN TO VERIFY AND FAILED (ship attempt 3, bash deploy/ship.sh from this worktree, 2026-10-06 ~21:35 EDT, log s2_ship3.log). Attempt 2's promote had been REFUSED before deploy ("no GREEN test-env suite run on record": the ledger reports/promotion-state.json is gitignored and per worktree, so the P5 GREEN record in the P5 worktree is invisible here); promote_env.py test test from this worktree gave 38,232 passed / 0 failed (RUL-032 reused all 1,928 modules; ledger test: validate=PASS@2026-10-07T01:27:16Z test=PASS@2026-10-07T01:28:14Z), the bare promote --to prod stopped at the --yes interlock, and the hand-run --yes --skip-ingest was denied by the session's permission classifier and not worked around; Mohamed then said "run the prod promote". Attempt 3: verify PASSED with the authoritative suite skipped (source-id 921ba704bfd13a1e already proven, reports/.ship-verified), run evidence committed as bfe6f0943, pushed, master fast-forwarded d23993eaa → bfe6f0943 (2 commits), all three deploy targets re-verified at bfe6f0943 (Claude config; /opt/orchestrata-tools 225 staged files + codemod_fast/ctok build; gitlab-runner 6 scripts). Promote: validate prod PASS (subnet 10.53.1.x, redis 10.53.1.10:6379 + graph 10.53.1.160:7691 reachable); resolve / infra / tree (287826a9 → bfe6f0943 reset --hard) / deps (uv.lock unchanged) / assets (units installed, 30 hooks executable) / record_version (VERSION bfe6f0943) / services (restarted ast-live-sync, conversation-consumer, gateway, kernel) all OK; verify FAILED after 90.4s: not active: orchestrata-conversation-consumer.service — the ADR-0072 R16b RuntimeError (CONVERSATION_KG_URI and CONVERSATION_KG_DATABASE not set, conversation_consumer.py:104) exited the unit three times and systemd hit its start-rate limit (NRestarts=3, "Start request repeated too quickly"), so the liveness line fired and the identity findings the third P5 ship reported (template-instance → P6; kg-retention / orchgraph-backup oneshots → PH1) were not listed this time. Rollback returned the tree to 287826a9af96 and restored the previous VERSION text, but its consumer restart failed identically ([FAIL] rollback … restart failed). Exit: FAILED prod @ bfe6f0943b2d, ship rc=1. Prod state measured afterwards: HEAD 287826a9, consumer failed, kg-retention failed (PH1), and /opt/orchestrata/VERSION names commit 7a5347cc (deployed 2026-09-23T18:14) rather than HEAD 287826a9 — a pre-existing VERSION/HEAD drift that rollback preserves verbatim (backlog (14)). None of the failures is S2 code; the S2 analysis package has no unit. Prod promote stays blocked on ADR-0072 (consumer env), P6 and PH1. @traces (REQ-110-031/032 only) on every class, method, function and test the packet adds SHIPPED: reports/rtm-evidence.{json,md} regenerated with --verify --verify-timeout 600 on the final tree (bb48acb2d, 2026-10-06, load about 2 on 16 CPUs, commit cb18b54eb): verified true, TESTED=339, FAILING=7, DECLARED=2975 (from TESTED=329 / FAILING=15 at the S1-verified 95d00f7ee). REQ-110-031 and REQ-110-032 TESTED (cited by the nine tests/refactor/codemod/analysis/test_*.py modules, test_cig_builder_ast.py and test_codemod_cli.py, all PASS); REQ-110-133/134/135/137 back to TESTED from FAILING (the P5 TestPidIsCodemodDaemon fix, merged from master). The seven red modules are all pre-S2 and red on master: tests/conftest.py (exit 5 harness artefact), test_full_pipeline, the three test_pipeline_e2e_*, test_context_pack_performance. A first regen on the merged tree (before bb48acb2d) graded REQ-110-031/032 FAILING because tests/refactor/codemod/analysis/__init__.py cited both ids in its docstring and collects no tests (exit 5); the ids were removed from that docstring (backlog item 13 records the verifier behaviour) and the regen redone. FIX ROUND 1: reports/rtm-evidence.{json,md} RESTORED to the S1-verified files (95d00f7ee; verified true, TESTED 329 / FAILING 15 / DECLARED 2975) because the static regen in cae1f22a4 downgraded the repo-wide RTM; the orchestrator runs the verified regen pre-ship (the first S2 regen had been static, CITED=346); trace_intel.py untraced-reqs does not list REQ-110-031/032 docs/codemod-analysis.md (new), checklist rows REQ-110-031/032 flipped to COMPLETE (totals 45 COMPLETE / 1 superseded / 5 NOT IMPLEMENTED), contract decision D26 (S2 classes designed to built, 2759b2857), S2 backlog paragraph above knowledge-wiki a8d3e03 (S2 section appended to projects/orchestrata-ultimate/modules/refactor.md: the seven analyzers, the analyze CLI additions, the resolver rework and the three memory reductions, the four carried backlog items); wiki ship 2026-10-07: a8d3e03 pushed to knowledge-wiki origin/master, RAG store re-indexed FIX ROUND 2 (measured 2026-10-06, line coverage over the 179-test group above): _cig_builder_ast.py 99% (3 of 374 missed: the _extract_annotation except branch and the keep < 0 relative-import guard), workspace.py 93%. FIX ROUND 1 (measured 2026-10-06, branch coverage on, tests/refactor/codemod without the perf/benchmark/memory-guard modules = 845 passed / 0 skipped for the source modules; test_codemod_cli.py = 52 passed for scripts/codemod.py via --cov=scripts.codemod), line coverage: _cig_builder_ast.py 97% (10 of 363 missed, all pre-existing _extract_* helper and class-flag branches; the resolver, sink_import and the op-log replay are 100%), workspace.py 98% (5 of 287 missed, none in load()'s file list), analysis/breaking_change.py 100%, analysis/complexity.py 100% (98% with branches), scripts/codemod.py 97% (12 of 401 missed: _cmd_run/main fallthroughs and the cycles body, all pre-existing paths). Before the fix round (94 tests): analysis/__init__.py 100%, abstraction.py 100%, blast_radius.py 100%, breaking_change.py 100%, complexity.py 100% (98% with branches), coupling.py 100%, dead_code.py 100%, encode.py 100%, metrics.py 99%, protocol.py 97% (the Protocol body ...), test_coverage.py 100% (99% with branches), _types.py 100% lines (93% with branches), scripts/codemod.py 95% (12 missed lines, all pre-existing paths: cycles body, _cmd_run diffstat and failure return, main auto-start and final return, _resolve_pass fallthrough)
S3 (build 24b856ccd; fix rounds 1-7 ending c6946173a; ADR-0073 2b8e510c0/570160a21; ship-prep 16edf7c68, RTM 48952a12a, records 4df23a51f; manifest edge 7bc6110f5) 2026-10-07 4fadfaac1 (40 commits fast-forwarded from bfe6f0943; the last is ship's own "record the authoritative run for 7bc6110f5"). SHIP ATTEMPT 1 (4df23a51f, rc 1, nothing pushed): verify's --affected refused with "NOTHING tests plans/contracts/spec-110-codemod-engine.contract.json" because test_review_catalogue.py reads the contract through a joined Path the reference-edge extractor cannot see; fixed by declaring the edge in plans/affected-tests-manifest.json with a proof test (test_spec_110_contract_json_change_resolves_the_catalogue_test; 127 passed across the two manifest modules). SHIP ATTEMPT 2 (7bc6110f5): RUL-032 reused 9 green modules, ran 63: 1,654 passed / 0 failed / 0 skipped in 111 s; ruff, black, RUL-007, rulings-lint, gen_plugin --check clean; pushed; master fast-forwarded. This row's final cells are committed after the ship and land on master with the next one, as the S2 row did. tests/refactor/codemod/ plus tests/scripts/test_codemod_cli.py on the final code, five parallel groups: 997 passed / 0 skipped; ruff, black, mypy and pyright clean; gate.py run PASS; check-deps --include-tests and check_spec_authority.py exit 0 deployed 2026-10-07 at 4fadfaac1 to the three ship targets, each verified: ~/.claude (143 files match, plugin 214 files match, hooks on the deployed venv), /opt/orchestrata-tools (228 files, codemod_fast + ctok rebuilt, every entry point and the observer shim resolve under /opt, none into a checkout), /opt/orchestrata-gitlab-runner (6 executor scripts, free-threaded venv) RAN TO VERIFY AND FAILED, rolled back (ship attempt 2): promote --to prod resolved 4fadfaac1, recorded VERSION, restarted 4 units, then the identity verifier refused on three items, none of them S3's: (a) the per-repo AST daemon template instance orchestrata-ast-daemon@…wt-SPEC-110.service is judged as an /opt/orchestrata unit although ADR-0067 P3 runs it from /opt/orchestrata-tools with a repo path as its instance argument (ExecStart/ExecStartPre/cwd/cmdline/start-time all "outside ROOT"), the P6/PH1 verifier-scope item; (b) orchestrata-kg-retention.service and orchgraph-backup.service oneshots in failed (P6/PH1); (c) rollback returned the tree to 287826a9 but orchestrata-conversation-consumer.service failed to restart on CONVERSATION_KG_URI and CONVERSATION_KG_DATABASE not set, the ADR-0072 question (Proposed, awaits Mohamed). Prod after rollback: gateway, kernel and ast-live-sync active on 287826a9, consumer failed, VERSION still reads commit 7a5347cc (backlog (14)). @traces on every new class, method and module function cites only REQ-110-033/034/035 (visitor visit_* dispatch methods are covered by their class); check_spec_authority.py PASS verified regeneration 48952a12a (generate_rtm_evidence.py --verify --verify-timeout 600): REQ-110-033/034/035 TESTED; trace_intel.py untraced-reqs lists no REQ-110 id; corpus 7,262 requirements, TESTED 342, FAILING 7, none of them SPEC-110's (backlog (15)) docs/codemod-review-engine.md (new page); checklist REQ-110-033/034/035 flipped, totals 48 COMPLETE / 1 superseded / 2 NOT IMPLEMENTED; contract D27 knowledge-wiki/projects/orchestrata-ultimate/decisions.md ADR-0073 entry (Proposed 3466762, Accepted bc14fbe, execution note 08da3b5, all shipped); modules/refactor.md gained the "packet S3 (in-memory review engine)" section after the ship, shipped through the wiki ship gate (sha in the wiki log) DOD-S3-5 command measured in two processes with branch coverage on (tests/refactor/codemod as one process exceeds the 300 s cap): review_engine.py 100% (118 statements, 18 branches, 0 missed), review_catalogue.py 95% (5 missed: the ... bodies of the ReviewCheck Protocol members), review_checks.py 99% (4 missed: the non-Compare return False of _is_main_guard, the non-call return False of _is_mutable_value, and two visit_AsyncFunctionDef bodies), workspace.py 93% (the commit wiring and _resolve_reviews are covered; the misses are pre-existing load and cache paths), analysis/metrics.py 99% (S2, untouched). FIX ROUND 1 (after reviewer NO-GO, 2026-10-06; commits on top of 2b8e510c0, no rebase/amend). Closed: delta baseline matches on a line-free message (_line_free strips L<n>:, (line <n>), line <n>; a prepended line no longer turns legacy findings into introduced ones); docs/codemod-observability.md states that a default commit emits the REVIEW_* events and that run_review_engine=False gives the old sequence; four false-positive causes (3a lexical checks read token-blanked text: SF_MOCK_PATTERNS blanks STRING/f-string text/COMMENT, the secret scan blanks COMMENT only because a literal secret value is its subject, the other lexical checks read raw lines; 3b CO_THIRD_PARTY_DECLARED reads [project] dependencies, every optional group, [dependency-groups] and [tool.uv] dev-dependencies plus the import names of declared distributions via importlib.metadata.packages_distributions(), the table check-deps uses; 3c _is_test_path needs a tests/test directory component or conftest.py; 3d CO_LOCAL_MODULE_EXISTS ignores imports that resolve outside the loaded roots, decided from the forest's path set); CX_CYCLOMATIC pinned at 10 clean / 11 flags; test_default_substrates_match_the_contract compares every row to the contract's check_catalogue. review_catalogue.py rows are unchanged. REQ-110-035 is recorded PARTIAL (checklist, docs). Carried item: phase-2 CIG is pre-mutation and unread by the five phase-2 checks (REQ-110-035 gap), design item, owner orchestrator. Final test run, five parallel groups over tests/refactor/codemod/ plus tests/scripts/test_codemod_cli.py: 1020 passed / 0 skipped; ruff, black, mypy, pyright clean; gate.py run PASS (after ast-sync); check-deps --include-tests and check_spec_authority.py exit 0. Coverage (line, the three review test modules plus the commit-wiring module): review_engine.py 100%, review_checks.py 99% (4 missed: the non-Compare return False of _is_main_guard, the non-call return False of _is_mutable_value, two visit_AsyncFunctionDef bodies), review_catalogue.py 95% (5 missed: the ... bodies of the ReviewCheck Protocol members). Fix round 1 re-measurement (reviewer's probe_engine.py logic, default include src,scripts,tests, every file an identity change, include_phase3=False, run once on an idle box, 2026-10-06; 3,234 files, load 35.7 s, review 88.1 s, 3,385 MB maxrss): 247 errors and 12,777 warnings; 100 files with at least one error, 19 of them under src/ or scripts/ (src 2 files, 5 findings; scripts 17 files, 20 findings; the other 81 files and 222 findings are under tests/). Errors by rule: SF_EVAL_EXEC 159 (136 "Possible hardcoded secret", 8 "Possible API key/token", 15 exec() calls), SF_FLUSHDB 29, TI_MODULE_FIXTURES 22, SF_ENVIRON_SUBSCRIPT 16, CO_THIRD_PARTY_DECLARED 13, TI_GLOBAL_STATE 8. SF_MOCK_PATTERNS no longer fires (it was the self-flagging pattern tables). Top five remaining error sites: (1) src/orchestrata_ultimate/gateway/config.py:59 _DEV_JWT_SECRET = «redacted» true positive by the rule (a secret-named literal; documented dev default); (2) src/orchestrata_ultimate/tools/task_tools.py:4,6,20,183, still a false positive: the sk-alternative of the API-key regex has no word boundary and matches insidetask-management-createin a docstring, and the reused function's regexes are outside this round's files; (3)scripts/serialize_codebase_ast.py:6957andscripts/janus_patched/janus/janus.py:411 exec(...), true positives by the rule (deliberate module loaders, flagged because the rule flags every exec); (4) scripts/ask_openrouter.py:19andscripts/check_staged_secrets.py:297, still false positives: docstring prose (ask-openroutercontainssk-openrouter; the second quotes api_token="your..."as an example of what the gate rejects); (5)scripts/sweep_test_pollution.py:98, scripts/attribute_traces_runtime.py:86,87, scripts/add_traces_from_evidence.py:45, scripts/architecture_static_check.py:38, scripts/_irc_listen.py:29, scripts/_irc_send.py:20 (CO_THIRD_PARTY_DECLARED), still false positives: bare sibling-script imports (import slot_lease, from generate_rtm_evidence import ...) resolved through sys.path; check-depstreats every module and package stem undersrc scripts tests claude as local (_local_module_names) and this engine does not yet. The tests/errors are mostly literal test credentials (secret-shaped literals) andflushdb/DELETE calls in shared fixtures, true positives by the rules as shipped. The CLI case (scratchpad/clirepo, scripts/codemod.py --repo clirepo --include src --no-daemon run --pass docstring-sweep --apply): exit 0, 0 files written, 0 findings (before the fix: success false, one SF_MOCK_PATTERNSerror on a mock-pattern table inside a string). **FIX ROUND 2 (after round-2 reviewer NO-GO, 2026-10-07; commits on top of ec696caf1, no rebase/amend).** Closed: (1+2) narrow-include scoping:CodemodWorkspace.load records the repo-relative include roots (include_roots, read-only), ReviewContext.include_rootscarries them, andCO_LOCAL_MODULE_EXISTSruns the reusedcheck_file_completenesson the raw forest path set and then drops findings whoseImport ''resolves outside every stored root (no stand-in path, no inference; the_scope_roots/_in_scope/_scoped_workspace_fileshelpers are gone); (7)_source_linesblanks per character, so column geometry holds in characters (non-ASCII case added to the blank-view test); (5) docs state the delta baseline's masking and measure-bearing-message limits (all warnings); (3) thesk-alternative of the API-key regex inchecks_safety.pyhas a left boundary(?<![A-Za-z0-9-])(rule text and severity untouched;task-management-toolandask-openrouterno longer match, a realsk-literal and anAKIAkey still do); (4)scripts/codemod.py _cmd_runexits 1 whensuccess is false in a dry run too. **Carried item: a review-aborted dry run has no diff preview (CommitReport.diffstatis empty on abort), design item, owner orchestrator.**baselinedefault stays'absolute'(ADR-0073 Proposed). Probes (own script, scratchpadr2_fix_probe.py, against this worktree): mixed module under --include src/orchestrata_ultimate/toolsimportingorchestrata_ultimate.core.base.traces(out of scope) andorchestrata_ultimate.tools.nope(missing, in scope) gives exactly oneCO_LOCAL_MODULE_EXISTSfinding, fororchestrata_ultimate.tools.nope; includes refactor/codemod/analysis+gateway/handlerswith a one-line append toanalysis/metrics.pyimporting the unloadedorchestrata_ultimate.core.base.tracesgive zero findings (before: error), and a missing...analysis.gonestill flags. Dry runscripts/codemod.py --repo --include src/orchestrata_ultimate/tools --no-daemon run --pass docstring-sweep --arg old=X --arg new=Y: exit 0, successtrue, 0 errors and 224 warnings (before: errors attask_tools.pylines 4/6/20/183); the same dry run with--include src/orchestrata_ultimate/gateway: exit 1, successfalse, one error,SF_EVAL_EXEC gateway/config.py:59"Possible hardcoded secret" (true positive, stays). Tests:tests/refactor/codemod/in four groups 204 + 291 + 258 + 122 = 875 passed,tests/scripts/test_codemod_cli.py53 passed (incl. the dry-run/apply abort test),tests/verification/review/plustests/verification/test_checks_safety.py203 passed, 0 skipped; ruff, black, pyright clean;gate.py runPASS;check-deps --include-testsandcheck_spec_authority.pyexit 0. Coverage (line):review_engine.py100%,review_checks.py99% (4 missed, all pre-existing),workspace.py90%. **FIX ROUND 3 (after round-3 reviewer findings F1/F2/F3, 2026-10-07; commits on top of 838c56e98, no rebase/amend).** Closed: (F1)workspace._include_root(root, subdir)folds every include onto the repo root before it is stored (absolute,./src, src/, src//x/, src/../srcstore the repo-relative POSIX root;.stores no roots, alone or beside other entries, so nothing is dropped; an include resolving outside the root raisesValueErrornaming the include and the root, before any file is read);loadwalks the folded root so forest keys stay repo-relative for a..include that resolves inside the root; (F2)review_engine._top_levelgives a file directly underscripts/tests/claudeits stem, a package directory there its own name, the root'sinit.pythe root name, and keepssrc//...as; (F3) docs/codemod-review-engine.mdstates the measured truth (a full load stores the three roots and the scoping drops nothing; the reusedcheck_file_completenessreports a missing module only when the packageinit.pyis not in the forest) and the test is renamedtest_full_load_roots_drop_no_local_module_finding. Probes (scratchpad r3_probe_fix3.py, a copy of r3_probe.pythat passes the root to_include_root): absolute include of analysisplus an appendedanalysis.nope_r3import gives 1CO_LOCAL_MODULE_EXISTSfinding and 11 files (before: 0);./+trailing-slash roots give 2 for two missing modules; .storesroots=()and flags nothing;../elsewhereraisesValueError; r2_probe.pysection 5 unchanged (the mixed module still reports onlyorchestrata_ultimate.tools.nope). Whole tree (probe_engine_fix1.py, include src,scripts,tests, identity change per file, include_phase3=False): 3234 files, 242 errors in 98 files, 12780 warnings (before: 242 / 98 / 12779); CO_THIRD_PARTY_DECLARED13 to 6 (theirc*, add_traces_from_evidence, architecture_static_check, attribute_traces_runtime86/87 andsweep_test_pollutionsibling-script hits are gone; left: 4 vendoredscripts/_janus_patched/hits includingsetup.py:13 _find_swipl, which lives two directories down in scripts/_janus_patched/janus/, and attribute_traces_runtime.py:82 coverage); **OPEN, owner orchestrator: the same 7 sibling-script imports now surface as 7 CO_LOCAL_MODULE_EXISTSerrors ("module file not found in workspace"), because the reused_build_module_candidatesnever proposesscripts/.py, so the error total stays 242; the cure is a decision about how the reused file-completeness function sees sibling roots (extra drop rule in ReusedCheck, or candidates widened), outside this brief.** Dry runs (--no-daemon run --pass docstring-sweep): --include src/orchestrata_ultimate/toolsrc 0, 0 errors, 224 warnings (unchanged);--include src/orchestrata_ultimate/gatewayrc 1, 1 errorSF_EVAL_EXEC gateway/config.py:59(unchanged);--include scriptswithold=X new=Yaborts inside the pass (theXtoYedit corrupts a string literal and the native tokenizer raisesSystemError; a pass defect, not touched), with old=Args: new=Arguments:it gives rc 1, 33 errors (32CO_THIRD_PARTY_DECLAREDfororchestrata_ultimate/orchestrata_astimports, because a narrowscriptsload has nosrcin its forest, plus theSF_EVAL_EXECsecret hit) and noCO_THIRD_PARTY_DECLAREDon a sibling-script import. Tests:test_review_checks.pyplustest_review_engine.py85 passed (was 73),test_review_engine_commit_wiring.pyplustest_observability_wiring.pyplustest_workspace_load.py66 passed (was 58),tests/scripts/test_codemod_cli.py53 passed,tests/verification/review/161 passed, 0 skipped; ruff, black, pyright clean;gate.py runPASS;check-deps --include-testsandcheck_spec_authority.pyexit 0. Coverage (line):review_engine.py100%,review_checks.py99% (4 missed, pre-existing),workspace.py94%. **FIX ROUND 3b (orchestrator pick on the round-3 fork, 2026-10-07; commits on top of 7224208c9, no rebase/amend).** Cure (a):review_checks._resolves_to_sibling_module(message, workspace_files)sits beside_outside_include_rootsandReusedCheck.runapplies it in the same comprehension for thepath_tree_files_modulesshape; it drops aCO_LOCAL_MODULE_EXISTSfinding whose import's top-level nametophas/.pyor//init.pyinctx.workspace_filesfor a root inreview_engine._SIBLING_ROOTS (imported, not duplicated); a nested stem stays un-local and the reused candidate paths are untouched. Whole tree (probe_engine_fix1.py, include src,scripts,tests, identity change per file, include_phase3=False): 3234 files, **235 errors in 93 files**, 12780 warnings (round 3: 242 / 98); the 7 sibling-script imports (_irc_listen.py:29, _irc_send.py:20, add_traces_from_evidence.py:45, architecture_static_check.py:38, attribute_traces_runtime.py:86,87, sweep_test_pollution.py:98) are gone, so CO_LOCAL_MODULE_EXISTSis 0, not the briefed 1:scripts/_janus_patched/setup.py:13 _find_swiplwas never aCO_LOCAL_MODULE_EXISTShit, it is one of the 6CO_THIRD_PARTY_DECLAREDerrors (round 3 already listed it there) because the name is a nested stem, not a project module; and the file count is 93, not the briefed 92, becauseattribute_traces_runtime.py:82 coveragekeeps that file in the error set (98 minus the 5 files that held only sibling-import errors). Errors by rule:SF_EVAL_EXEC154,SF_FLUSHDB29,TI_MODULE_FIXTURES22,SF_ENVIRON_SUBSCRIPT16,TI_GLOBAL_STATE8,CO_THIRD_PARTY_DECLARED6 (5 vendoredscripts/_janus_patched/hits: twojanus_swi.py, setup.py:13, xsb_tests/numpexamp.py, xsb_tests/testc.py; plus attribute_traces_runtime.py:82 coverage), CO_LOCAL_MODULE_EXISTS0;gateway/config.py:59 SF_EVAL_EXECunchanged. Dry run--include scripts --pass docstring-sweep --arg old=Args: --arg new=Arguments:: rc 1, 33 errors (32 CO_THIRD_PARTY_DECLAREDonorchestrata_ultimatex25 andorchestrata_astx7 imports, plusSF_EVAL_EXEC serialize_codebase_ast.py:6957), 792 warnings, no CO_LOCAL_MODULE_EXISTS. Tests: test_review_checks.pyplustest_review_engine.py89 passed (was 85),test_review_engine_commit_wiring.pyplustest_observability_wiring.pyplustest_workspace_load.py66 passed,tests/scripts/test_codemod_cli.py53 passed,tests/verification/review/161 passed, 0 skipped;review_checks.py99% (4 missed, pre-existing),review_engine.py100%. Docs: one sentence on the sibling rule in the "Narrowinclude" paragraph. **CARRIED, not fixed here:** (1) narrow include without src reports the repo's own packages as third-party (orchestrata_ultimate, orchestrata_aston ascripts-only load) - scope rule for CO_THIRD_PARTY_DECLARED, design item, owner orchestrator; (2) docstring-sweep with a substring that lands inside a string literal (old=X new=Yon--include scripts) raises SystemErrorinstead of a finding or a refusal - owner: S4/S5 hygiene. **FIX ROUND 4 (round-4 reviewer findings, orchestrator picks 2026-10-07; commits on top of 4d4334679, no rebase/amend).** R4-1 (tests):_review_after_appendnow loadsinclude=("src", "scripts", "tests"), so the completeness finding survives _outside_include_roots(the reused candidatesrc//init.pylies under a stored root) and only the sibling rule can drop it; every sibling test assertsCO_LOCAL_MODULE_EXISTS == [](or the kept finding) explicitly,test_sibling_script_import_is_not_an_undeclared_third_partyasserts both import rules absent, andtest_sibling_rule_is_the_only_thing_dropping_the_findingshows the reusedcheck_file_completenessreportsImport 'b'on the same forest. Proof: removingand not _resolves_to_sibling_module(...)fromReusedCheck.run locally fails 4 tests (test_sibling_script_import_present_in_the_forest_is_not_a_missing_local_module, test_sibling_rule_is_the_only_thing_dropping_the_finding, test_sibling_package_import_present_in_the_forest_is_not_a_missing_local_module, test_sibling_script_import_is_not_an_undeclared_third_party); restored, never committed. R4-2 (**D27 note**, an implementation refinement inside contract D27, not an ADR): sibling locality is importer-scoped. review_engine._top_level returns the pre-round-3 answer (src/gives, anything else its first component); the new review_engine._sibling_name(path)returns the stem or package directly under a sibling root;_sharedkeepsproject_modulesand addssibling_modules; _contextgives a path under a sibling rootproject_modules
S4 (build 293afd07b..3a29ee3d0; fix rounds 1-4 ending 12b5e8188; brief 293afd07b + §§5-8 to e324c3849; contract D29 daec60c25/be07be5a4; RTM be07be5a4) 2026-10-07 3288ca146 (28 commits fast-forwarded from 57cf64e44; the last is ship's own "record the authoritative run for be07be5a4"); PROD PROMOTE NOT RUN (--no-promote): the prod graphs stage is blocked on the OpenRouter balance (F-P6a-2, ADR-0074 Proposed), so this ship moved the three ship targets and master only; prod stays at ab189ccc7 ship verify --affected from be07be5a4: 1164 passed / 0 failed / 0 skipped over 41 modules in 220 s (4 modules reused under RUL-032); one module recovered on solo retry, test_daemon_lifecycle.py, whose new dying-launcher test asserted elapsed < 3.0 and measured 6.98 s in the 8-worker batch (2.0-2.8 s solo) — FIXED in the next ship (the bound is replaced by the deterministic "deadline text absent" check, and the H5 CLI test's bound becomes the 60-s wait it guards); gates: ruff, black, RUL-007, rulings-lint 35 verified, prolog boundary, gen_plugin --check clean deployed 2026-10-07 at 3288ca146 to the three ship targets, each verified: ~/.claude (VERSION 3288ca14, hooks on the deployed venv), /opt/orchestrata-tools (every entry point, the observer shim, ast-daemon and codemod-daemon resolve under /opt, none into a checkout; ast-daemon /health deployed_commit=3288ca146; the wt-SPEC-110 AST daemon instance restarted because its code moved beneath it), /opt/orchestrata-gitlab-runner NOT RUN (--no-promote; see Master sha) @traces on every new function and test (_connect_or_warn, _pass_spec, _run_via_daemon, _PendingRun, replace_workspace, _fits_between_quotes, _docstring_nodes, _settle_after_start, _unit_show, …) cite REQ-110-010/133/135/137/138/140; check_spec_authority.py PASS verified regeneration be07be5a4 (generate_rtm_evidence.py --verify, 196 citing modules replayed): REQ-110-140 TESTED (was CITED), 110-codemod-engine 41 TESTED / 0 FAILING / 7 DECLARED / 11 UNLINKED; corpus TESTED 343, FAILING 7 (the same six llm_integration/skip-marked modules and conftest as the S3 regen; backlog (15)) docs/codemod-daemon.md (new page, kept current through rounds 1-4); checklist REQ-110-140 [x] with the S4 backlog qualifier, totals 48 COMPLETE / 2 IN PROGRESS / 1 NOT IMPLEMENTED; contract D29 with refinements R1-R13 and all 21 S4 commits knowledge-wiki/projects/orchestrata-ultimate/modules/refactor.md "packet S4 (the CLI uses the daemon it can start)" section covering all four rounds, commit bc4d02a, shipped through the wiki ship gate (pushed to origin/master, rag-store rebuilt) measured after round 3 in single-module processes: server.py 98 % (9 missed of 424), passes.py 99 % (5 of 420), scripts/codemod.py 98 % (9 of 565); after round 4 daemon.py 92 % (23 of 303; the uncovered branches are the deadline raise and the zero-MainPID raise, which the measured window does not reach)