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
- D1 — RULED (ADR-0068, Accepted; Mohamed 2026-10-06: "go with
recommendatio . build s3'"). REQ-110-034 amended in
specs/110-codemod-engine/spec.md: checks run on the ctok token array + the forest's CPythonastoverlay, no re-parse/subprocess/external linter, structural checks asast.NodeVisitor, lexical checks as token scanners, reuse ofverification/review/check_*. S3 unblocked; it builds against the S2/S3 contract extension once committed. - D2 (operational, recorded here). Analysis passes (REQ-110-031) are thin
read-only adapters over the existing
CodeIntelligenceGraphqueries that return the existing_types.pydataclasses (BlastRadius,BreakingChange,CouplingScore,AbstractionLevel); no second graph. - D3 (operational). REQ-110-025/027 are built exactly per
plans/codemod-observability-wiring-design.md(reusecore.patterns.observer.SyncObservable; delete the redundantObserverredeclaration inobservability/events.py, re-export the core one). - D4 (sequencing). S4 (REQ-110-140) touches
scripts/codemod.py, which ADR-0067 P4 is also changing (--auto-start→CodemodDaemon.start). S4 builds AFTER P4 lands on master and this branch has merged master. - D5 (operational, from the S2/S3 contract extension 9f7ee385d). REQ-110-035
assigns Safety no phase; every Safety check is file-local and needs no graph,
so Safety runs in phase 1 (phase 1 = 30 ids, phase 2 = 10; phase 3 is
PrologSemanticReview, outside the 40). - D6 (operational — spec-settled, RUL-013).
InMemoryReviewEnginetakesbaseline='absolute'|'delta'and defaults to'absolute': ERR-110-002 says an error finding aborts the commit, and the spec names no legacy carve-out.'delta'(findings the pass introduced) is an opt-in. Flipping the default is a spec amendment and needs its own ADR; none is minted until a packet measures a legacy-file abort in practice. Superseded by ADR-0073 (Accepted 2026-10-07): the default is'delta';'absolute'is the opt-in. - D7 (operational).
CodemodWorkspace.commit()gainsreview_engine=andrun_review_engine=True; withreviews=Noneit builds and runs the default engine before write-back (REQ-110-033/035 say review runs on commit). S3 measures which existing commit tests gain findings and fixes code, not tests (RUL-002).BannedConstructsstays for callers who pass it; its overlap with three Safety checks yields duplicate findings by design. S3 measurement (2026-10-06, wholetests/refactor/codemod/plustests/scripts/test_codemod_cli.py, run before the fix): no existing commit test gained a real finding, so no fixture code changed. Two tests failed on the event sequence, not a finding:test_observability_wiring.py::TestCommitEvents::test_real_commit_writes_files_and_completes(asserts exactlyCOMMIT_STARTED,COMMIT_COMPLETED) and::test_failed_write_emits_rollback_error_and_aborted(assertskinds[0]isCOMMIT_STARTEDand indexesevents[1]/events[2]). The default engine addsREVIEW_STARTED/REVIEW_COMPLETEDin front, which is the specified behaviour (REQ-110-033/035); both tests now passrun_review_engine=False, an assertion-for-assertion unchanged write-path test, and the review-event sequence of a default commit is asserted intest_review_engine_commit_wiring.py(TST-110-026). - D8 (operational).
scripts/codemod.py analyzekeeps the existing--querychoices and appendsbreaking_changes,complexity,test_coverage,dead_code,all-passesplus--json;breaking_changestakes--modulewith--base <git ref>(the minimal input shape in contract decision D24). - D9 (operational). The S2/S3 contract's six
analysis_gaps(no graph reachability query,CALLSfirst-match resolution, same-fileTESTED_BY,_CSRIndexover all edge types,breaking_changeswithout signature diff, no complexity query) are S2 scope where the analyzer can compute the answer from the forest's ast overlay, and recorded as owed graph work (backlog) where the fix is aCodeIntelligenceGraphmethod the contract does not add.
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.
-
Round 1 (2026-10-06): HOLD. Blocker: two passes editing one file could not commit (
ConcurrentEditError, the second pass'soriginal_treewas the first pass's output). Minors: observer dedupe, failure-path test depended on chmod (not root-proof),@tracesmissing onobservable/subscribe, REQ-110-006 checklist row false ([x], see S5 findings). Fixed in fabc26225, f570bd781, b9bac8a9c; master 2893e2b6b merged in f05ed90f8; checklist wording 1c96fb717. -
Round 2 (2026-10-06, against 1c96fb717): HOLD. Round-1 blocker confirmed fixed by an independent probe (both edits on disk; external edit between load and commit still refused;
ChangeSet.mergecorrect for three passes and a path touched only by a later pass). New findings:- B1
commit()now writes throughtxn.commit_changes, whose_write_atomiccreates the temp file withmkstemp(0600) and renames it over the target without copying the original mode: a 0755 script becomes 0600 and every touched file loses group/other read. Reached fromscripts/codemod.py run --apply; 23 trackedscripts/*.pyare 100755. No test asserted file mode. Fix:fstatthe target andfchmodthe temp file before the rename, plus a test that commits a 0755 file and reads the mode back. - M1 checklist row REQ-110-034 (line 110) still carries the pre-ADR-0068 LibCST wording; only the summary at line 158 was updated.
- M2 checklist line 156 says FR-001..FR-007 are COMPLETE while REQ-110-006
is
[ ]. - M3 the five REQ-110-026 observers have no production constructor:
_default_observers()is called only by a test. Design §5/§7 sanction an empty default, so REQ-110-027 is met in letter but "override defaults" is vacuous. Resolution recorded as D10 below. - M4 dedupe is identity-based in
_Operation.__init__butcore.patterns.observer._SubscriptionRegistry.subscribeusesnot in(equality): an observer with__eq__(a dataclass) equal to one already subscribed is dropped. All five built-ins are identity-eq. The core module is out of S1 scope (as for ERR-110-011); S1 documents the limitation in design §8 and the checklist row; the core fix is owed to the owner ofcore/patterns/observer.py(identity check in the registry). - N1
@tracesstory ids on the observability code cite US-110-009 / US-110-003; the observability story is US-110-005. - N2
run(p1)→commit(dry_run=True)→run(p2)→ real commit raisesConcurrentEditError"modified concurrently" although nobody edited the file (p2'soriginal_treeis p1's in-memory output). Refusal is defensible, the message is wrong. - N3
_Operationsnapshots the workspace bus at construction; an observer subscribed by another thread mid-operation can be delivered twice. Rare. - N4
reports/rtm-evidence.mdmarks REQ-110-140 TESTED on the strength oftests/scripts/test_check_requirement_corpus.pywhile the checklist says NOT IMPLEMENTED — RTM-generator false confidence, separate owner. - Gates:
check_spec_authority.pyPASS (REQ-110-127 lives in the checklist FR-CTOK section and the gate unions everyREQ-token underspecs/, so thepasses.pycitation stands);check-deps --include-testsexit 0;gate.py runexit 2 (fact base stale, 38 files; refresh withscripts/gates.pythen re-run); targeted pytest 139 passed / 0 skipped. The ship-log coverage note "perf-band tests excluded" names neither the tests nor the reason.
- B1
-
Fix round 2 (2026-10-06): B1, M1, M2, M3 (D10), M4 (documented), N1, N2 and the ship-log coverage note closed in 41bd131d5. N3 stays a recorded note (rare double delivery, no change) and N4 stays with the RTM-generator owner. Gates after the fix:
gates.pyALL PASS,gate.py run0,check-deps --include-tests0,check_spec_authority.py0; targeted suites 153 passed, 0 skipped. -
Round 3 (2026-10-06, against 7bea607dd): HOLD. B1, M1, M2, M3/D10, M4, N1, N2 and the 43/1/7 counts confirmed closed; the
--observerun attaches and closes all five observers on the success and failure paths (reviewer probe). New findings:- R3-B1 regression from the B1 fix:
_write_atomicnow copies a 0444 target's mode onto the replacement, so_rollback'swrite_bytesgets EPERM on that file. A two-file commit whose second write fails leaves the first (read-only) file with the NEW content, masks the original exception with the rollback'sPermissionError, and never emitsROLLBACK_TRIGGERED— REQ-110-014's byte-exact rollback is broken for read-only targets. Pre-fix, the same scenario rolled back. Fix:_rollbackrestores through the same tempfile + rename path with the snapshot's mode applied after the write; a test with a 0444 first target and a forced second-write failure (root-proof: the latin-1CommitVerificationErrortechnique, not directory permissions). - M-a setuid/setgid are dropped:
fchmodruns beforeos.writeand the kernel clears them on write (0o4755 → 0o755,0o2755 → 0o755). Eitherfchmodafter write + fsync, or narrow the "keeps its permission bits" wording in docs and design §8 to what holds. - M-b
test_run_observe_apply_attaches_the_five_observersproves only the DebugPanel artefact; adefault_observers()returning one observer would pass.test_run_without_observe_attaches_no_observershas no@traces. - M-c docs/design §8 claim "a new file gets the mkstemp default 0600" but
commit()cannot create a file (_check_concurrent_editsraisesFileNotFoundError); the branch is reachable only when the target is deleted between the check and the write, and then the file is silently resurrected at 0600. Pre-existing race; the wording is new and must be honest. Resurrection itself is recorded as owed (REQ-110-015 hardening). - M-d the ship-log coverage note omits
test_memory_guard, the test that failed under--cov(3.7634 GB vs the 3.5 GiB = 3.7581 GB band), and does not say the round-2 coverage run had failures. - N-a checklist row 034 abridges spec.md:943 (drops the lexical-check list and "rather than re-implement it"); meaning unchanged.
- N-c
--observeattaches afterload(), soWORKSPACE_LOADED/INDEX_BUILTnever reach the trace; docs say "for this run and commit", which is accurate. Gap for US-110-005, not a defect. - N-d the two coverage-run failures are unrelated to 41bd131d5 (it touches
neither
load()nor any daemon module); the orchestrator's idle no-coverage rerun of both modules: 87 passed. - N-e
_write_atomicleaks the temp file iffchmod/write/fsyncraise aftermkstemp(pre-existing for write/fsync). - Gates:
check_spec_authority.py0,check-deps --include-tests0,gate.py run2 (fact base stale again: the refreshedplans/ast-*.jsonare restored as hook litter before every commit, sogate.py runpasses only immediately afterscripts/gates.py; record the pass at that moment); four targeted modules 153 passed, 0 skipped.
- R3-B1 regression from the B1 fix:
-
Fix round 3 (2026-10-06): R3-B1, M-a, M-b, M-c, M-d and N-e closed in ecd2ca88c. N-a and N-c need no change. Measured as uid 1001 (non-root):
0o4755and0o2755both round-trip throughcommit_changes(fchmodnow runs afteros.write; docs and design §8 state exactly this, no narrowing needed)._rollbackrestores through the tempfile + rename path with the snapshot's mode (_FileSnapshot.mode); a vanished target raisesConcurrentEditError("no longer exists"), so_write_atomicno longer creates files and the new-file 0600 test is replaced. The--observeCLI test records which observer classes'on_eventran (profile hook, no mocks) and requires all five. Coverage over the codemod suite +test_codemod_cli.py(814 passed, 0 skipped; perf/benchmark/memory-guard excluded): codemod.py 96%, txn.py 93%, workspace.py 98%. Gates after the fix:gates.pyALL PASS,gate.py run0,check-deps --include-tests0,check_spec_authority.py0. -
Round 4 (2026-10-06, against e73d1ede3): HOLD. M-a, M-b (mostly), M-d, N-e and the written-0444 R3-B1 scenario confirmed closed (probe: original exception surfaces,
ROLLBACK_TRIGGEREDwith 2 files, both restored, 0444 kept; all six modes round-trip; no temp files on any injected failure; thesys.setprofileCLI test is observation,audit_test_purity.py0 violations). One root cause remains:- R4-B1
_rollbackrewrites EVERY snapshot entry, including entries that were never written. (i) When the forward write failed because the target's directory is not writable, the rollback'smkstempfails in the same directory inside theexceptblock: the rollback'sPermissionErrorsurfaces with the original as__context__,ROLLBACK_TRIGGEREDis never emitted (regression from ecd2ca88c:write_byteson an unchanged writable file used to succeed). (ii) A target deleted between the concurrent-edit check and the write correctly raisesConcurrentEditError("no longer exists")and is then RECREATED by the rollback, so the docs/design claims "commit()never creates a file" and "instead of being recreated" are false;test_write_atomic_refuses_a_vanished_targetcalls_write_atomicdirectly and never reaches the rollback. Fix: restore onlyfiles_written(unwritten entries are unchanged on disk by construction) and catch per-file rollback errors so the original exception and the event always win; addcommit_changes-level tests for a vanished target and for a never-written entry whose rollback cannot write (root-proof: target path is a directory). - M1 the setgid bit survives but the GROUP does not: the rename swaps in
an inode owned by the writer's egid (
gid 100 → 1007), so "0o2755 survives" is literally true and semantically false; the same holds for uid ownership since the round-2 rename approach. Fix:fchown(fd, -1, st_gid)beforefchmodwhere the caller may, or narrow the docs to what holds (uid cannot be preserved without root). - M2 the five-observer CLI test fills ONE set across
codemod.main; an observer that saw onlyrun()or onlycommit()events passes. Record(type, event_type)pairs and require each type to have seen apass_*and acommit_*event. - M3 the ship-log row says "N-d records two" coverage failures but names
only
test_memory_guard. The second (builder round-2 report) was atests/refactor/codemod/test_daemon_lifecycle.pyargv probe that failed once under--covand a different test in that module failed on the solo re-run; both modules pass at idle load without coverage (87 passed). Name it. - Notes: the
setprofilehook restores toNonerather thansys.getprofile()(clobbers an outer profiler; none in this suite); the stat→rename TOCTOU window still resurrects a file deleted insidemkstemp(inherent withoutrenameat2; docs must not overstate); a 0200 target the user owns fails cleanly in_check_concurrent_edits;ConcurrentEditError(vanished=)is keyword-only and backward compatible. - Gates:
check_spec_authority.py0,check-deps --include-tests0,gate.py run2 (stale fact base, as before); four targeted modules 157 passed, 0 skipped.
- R4-B1
-
Fix round 4 (2026-10-06): R4-B1, M1, M2, M3 closed in fdfc5b25b. R4-B1:
_rollbackreceives onlyfiles_written; each per-file restore is wrapped, logged, attached to the original exception withadd_noteand listed in theROLLBACK_TRIGGEREDpayload (rollback_failures), and the event is always emitted. The brief's "target path is a directory" never-written probe does not reach the write:_check_concurrent_editsfails first on the directory (os.readraisesIsADirectoryError, outside the rollback try), so the never-written and rollback-failure tests useRLIMIT_FSIZE(EFBIG for every uid; Python ignores SIGXFSZ). That needed one production change in_replace_file:os.writeis looped, because with the cap it returned a short count and the truncated temp file was renamed over the target. M1, measured as uid 1001 (gid 1007, member of 100/0/1/65534):fchown(fd, -1, gid)on a member group is kept, on foreign group 2000 it gives EPERM and the file keeps gid 1007; sofchownruns beforefchmodand aPermissionErroris swallowed only for a non-member group. The uid cannot be preserved without root; docs and design §8 say so. The stat to rename TOCTOU window is stated as open. M2: the CLI test records(observer class, event type)pairs, asserts each of the five saw apass_*and acommit_*event, and restoressys.getprofile()'s prior value. M3: ship-log coverage column names the second failure. Gates:gates.py0,gate.py run0,check-deps --include-tests0,check_spec_authority.py0, purity audit 0 violations. Coverage (codemod suite +test_codemod_cli.py, same three exclusions): txn.py 95%, workspace.py 98%, scripts/codemod.py 96%. -
Round 5 (2026-10-06, against d4d7da71a): HOLD. R4-B1 confirmed closed by the round-4 probes A/D/F (original exception surfaces,
ROLLBACK_TRIGGEREDalways emitted withfiles_rolled_backandrollback_failures, nothing resurrected); write loop correct underRLIMIT_FSIZE(target never replaced by truncated bytes, no leftovers);add_notesurvives the re-raise; M2 and M3 closed; the rlimit tests are per-process and the 8-worker executor is one process per module; purity, parallel-safety and isolation audits 0 violations. New findings:- R5-B1 regression from fdfc5b25b:
_replace_file'sfchown(fd, -1, gid)catches onlyPermissionError. Underunshare -r(rootless containers, bubblewrap) a host group the writer is in but which is not their primary group stats as gid 65534 (unmapped) andfchownraisesOSError(EINVAL), so EVERY commit of such a file fails; the parent commit committed fine. Inside the namespaceos.getgroups()also reports every unmapped group as 65534, so the membership check is wrong there too. Fix: treatEPERMandEINVALas "group cannot be preserved", log a warning naming the path and both gids, continue; regression test runs the commit in a child underunshare -ragainst a filechgrp'd to a non-primary group the writer belongs to. Preserving gid beforefchmoddoes NOT reintroduce the setgid clearing (probe:0o2755gid 100 survives). - M-a
test_rollback_of_the_written_set_never_recreates_a_vanished_pathcalls_rollbackwith a hand-built dict that never contains the vanished path, so it cannot fail for the bug it names; only the inode assertion intest_rollback_restores_only_written_entriesguards the rollback scope. M-btest_commit_refuses_a_target_deleted_before_the_writefails in_check_concurrent_editsbefore thetry; its name overstates. Resolution: onecommit_changes-level test where another thread deletes the second target once the first entry's temp file appears (first payload large enough to make the window reliable; run it 20× before trusting it); if it cannot be made deterministic, rename both tests to what they prove and record the gap in design §8. - M-c rollback recreates a WRITTEN file deleted after its write, and overwrites an edit made after its write (probes R/S). Intended semantics (restore the pre-commit state), but docs and design §8 must say so.
- M-d (P4 code, for the P5 owner)
TestPidIsCodemodDaemonflakes becausePopenreturns before the kernel fills/proc/<pid>/cmdline(measured 163/300 empty right after spawn); the production predicate returning False on an empty cmdline is the fail-safe direction, the race is in the TEST —wait_untilthe cmdline is non-empty and contains-mbefore asserting. Failed 2 of 5 runs without coverage; coverage is not the cause. - Notes:
rollback_failureselements are"path: ExcType: message"strings (document the shape); "never replaces the original exception" holds for the production sink (SyncObservable.emitswallows observer errors) but not for a directon_eventcallable that raises — qualify the docs or wrap the sink call. - Gates:
check_spec_authority.py0,check-deps --include-tests0, purity audit 0,gate.py run2 (stale fact base); targeted pytest 145 passed, 0 skipped.
- R5-B1 regression from fdfc5b25b:
-
Fix round 5 (2026-10-06): R5-B1, M-a, M-b, M-c and both notes closed in a4bc5e436 (M-d stays with the P5 owner). R5-B1:
_replace_filetreatsOSErrorwitherrnoEPERM or EINVAL fromfchownas "group cannot be preserved" (warning with path, wanted gid, resulting gid) and continues; theos.getgroups()test is gone. Measured as uid 1001 (egid 1007, member of 100) with a filechgrp'd to 100 and committed underunshare -r: at HEAD (678114085)fchownraisedOSError(22)and the commit exited 1, file unchanged; with the fix the namespace saw file gid 65534, warned "wanted gid 65534, file keeps gid 0", exited 0, and the host sees the new file with gid 1007. The regression testtest_commit_succeeds_when_the_group_is_unmapped_in_a_user_namespaceruns that commit in a child (/usr/bin/unshare -r,sys.executable, worktreesrconPYTHONPATH); with no supplementary group it falls back to a foreign gid 2000 through_replace_file. M-a/M-b: onecommit_changes-level test (test_commit_refuses_a_target_deleted_during_the_first_write, an 8 MB first payload, a second thread deleting the second target once the first*.tmpappears) ran 20/20 green in 20 separate pytest processes, so it ships; the hand-built-dict_rollbacktest was deleted (it could not fail for the bug it named) and the pre-check test was renamedtest_commit_refuses_a_target_already_deleted_when_commit_starts. M-c and therollback_failuresshape are indocs/codemod-observability.mdand design §8. Note: a raisingon_eventsink is now logged and swallowed incommit_changes(testtest_a_raising_event_sink_never_masks_the_commit_failure). Gates:gates.pyALL PASS (0),gate.py run0,check-deps --include-tests0,check_spec_authority.py0, purity audit 0. Codemod suite +test_codemod_cli.py(perf, benchmark and memory-guard excluded): 822 passed, 0 skipped; txn.py 95%. -
Round 6 (2026-10-06, against bb93967bb / a4bc5e436): GO. No blocker. Reproduced by the reviewer on HEAD:
probe_ns.pyunderunshare -ron a freshchgrp 100fixture (namespace sees gid 65534, warning names path and both gids, commit OK, host file gid 1007 mode 644);probe_r4/probe_r5scenarios all match the documented semantics (R: a deleted written file is recreated with the old bytes; S: a later edit is overwritten; U:rollback_failuresis a list of"path: ExcType: msg"strings); the unshare test's child imports the worktreesrc(txn.__file__under wt-SPEC-110,PYTHONPATHahead of the editable.pth) and has no skip path (missingunshareerrors, disabled userns fails the rc assertion, a hang hitstimeout=120); pre-fixsrc(git archive a4bc5e436^) fails both child modes withOSError(22); the vanished-target test passed 10/10 in separate processes (0.45–0.97 s) with no vacuous path and a bounded deleter thread (30 s deadline,joininfinally);caplogis pytest's built-inLogCaptureFixture; the surfacedPermissionErrorhas__context__None. Nothing else imports_FileSnapshot/_rollback;_rollback's failure branch is still covered. Branch diff vs origin/master: 23 files, all S1 scope. Gates (run directly, not viagates.py, to avoid ruff --fix/black edits):check_spec_authority.py0,check-deps --include-tests0 (59 declared), purity audit 0,gate.py run2 (stale fact base, expected outside a freshgates.py), four targeted modules 165 passed / 0 skipped. Three MINORs, all record-level: (1) design §8 still stated the round-4 group-membership rule in present tense — rewritten as history (fixed in this commit); (2) the ship-log S1 row stopped at the round-3 numbers — filled at ship time below; (3) the fix-round-5 record saysgate.py run0 where the reviewer measured 2 — the 0 holds only immediately aftergates.pyrefreshes the fact base (the standing note in §0 applies; both figures are consistent with that), and the fix-round-4 "145 passed" vs the reviewer's 165 differ by module set (round 4 ran three modules, round 6 ran four). Notes (no action, owner S5 hygiene):fchownruns even when the temp file's gid already equals the target gid, so a filesystem rejecting chown with EOPNOTSUPP/ENOSYS (some FUSE mounts) fails a commit that succeeded before group preservation — skippingfchownwhenos.fstat(fd).st_gid == gidcloses it; the unshare test asserts rc/content/no-litter but not the warning text in stderr; the raising-sink test asserts the log line but not__context__ is None. Not re-verified by the reviewer: the 20/20 loop and the 822/95% coverage run (outside the targeted scope). Reviewer evidence under the session scratchpad (r6_loop10.txt,r6_targeted.txt,r6a/,r6old/,r6m_*). -
D10 (operational). The default observer set stays empty (design §5/§7).
scripts/codemod.py rungains--observe, which attaches the five REQ-110-026 observers for that run and commit, so the built-ins have a production constructor and REQ-110-027's "override" has a referent._default_observersbecomes the publicdefault_observers(). No ADR: the design already fixed the empty default; this is wiring (RUL-023).
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.
- Review round 1 (NO-GO, against cae1f22a4) → fix round 1 (2026-10-06;
RTM restore 147b47979, code f6a67f847, docs and plan in the commit after it).
-
BLOCKER-1 IMPORTS edges almost never resolved. Cause in
_cig_builder_ast.py:_record_importlinked an import only to an ALREADY-registered module, and_module_name_to_pathturnedpkg.modintopkg/mod.py, ignoring include roots (src/), packages (pkg/__init__.py) and relative levels. Fix: the extractor records raw imports (sink_import; op"i"in the parallel op log);_CIGBuilder.buildresolves them in a second pass over the finished module table with_ImportResolver(ancestor directories of a non-package importer, repo root, top-level directories, inferred package roots; relative imports by level;from pkg import namepreferspkg/name.py, elsepkg/__init__.py; a package directory is not an implicit import root, soimport logginginside a package never binds a siblinglogging.py). One IMPORTS edge per (importer, importee) pair. The Import node now carries its statement's realline,level,is_relativeand aresolved_moduleproperty.CodemodWorkspace.load()sorts its file list (one line;commit()untouched). NoCodeIntelligenceGraphmethod and no CSR shape change (D9 stands). Existing assertions: none encoded the old behaviour; two comments that described the one-pass limitation were rewritten (test_cig_builder_ast.py,test_workspace_load.pydocstring) and the analysis conftest docstring (it told fixtures to order importees first). -
MAJOR-2 RTM:
git checkout 95d00f7ee -- reports/rtm-evidence.{json,md}committed (147b47979). The committed RTM is the S1-verified one (verifiedtrue; TESTED 329, FAILING 15, DECLARED 2975, identical to 95d00f7ee) pending the orchestrator's verified pre-ship regen;--verifywas not run here. -
MINOR-3
_signature_ofignored async-ness: anasyncmarker now heads the signature tuple (def to async def, and back, is a changed signature, US-110-003).test_each_changed_signature_reaches_each_importerhad locked the old behaviour in ("keep became async: not a signature change"); it now expectskeep: signature changedonce per importer. -
MINOR-4
BreakingChange.consumer_linewas the module node's line 1. The detector reads the Import nodes (resolved_module+line) and reports the first importing statement's real line; the CLI fixture'sapp/user_a.pynow has a docstring so the line is 3 and the assertionapp/user_a.py:3 <- src/lib.pyis distinguishable from the old:1. -
MINOR-5
ComplexityAnalyzermixedpath:name(class dropped, duplicates for same-named methods) withpath:Class.method.qualified_nameis now always<path>:<dotted scope>from the AST walk; the graph only resolves the target module.test_fixture_functions_have_exact_metricskeyedsrc/lib.py:mul; it now keyssrc/lib.py:Calc.mul. -
MINOR-6
all-passes --jsonwithout--module: chosen option = summary counts for the per-module mapping (D24 allows either). A BlastRadius entry becomes{affected_node_count, affected_file_count, impact_score}; coupling and abstraction entries were already numbers. Real repo: 160 MB / 2m32s before, 14.0 MB / 1m51s after (the per-module mappings total 1.1 MB; the remaining 12.6 MB is the repo-wide per-functioncomplexityreport, which is the pass's content, not the mapping; the time is the per-module blast-radius BFS plus the 21 s load). -
NOTE
_changes_sincerunsgit show <base>:./<path>, so--repomay be a subdirectory of a git repository. -
Probe (
CodemodWorkspace.load(Path("."), parallel=True)on this worktree, thenDeadCodeDetector,CouplingAnalyzer):cae1f22a4 f6a67f847 modules 3226 3226 IMPORTS edges total / into src/324 / 2 7926 / 7422 unreachable modules (all) / non- __init__src/modules818 / 818 0 / 0 core/base/traces.pycouplingefferent 7, afferent 0, instability 1.0 efferent 7, afferent 620, instability 0.0112 0 unreachable is correct for the shipped roots (every module under
tests/is a root and the tests import nearly everysrc/module); a stricter probe rooted atscripts/plus__main__.pyonly, run once, reports 265 of 833 non-__init__src/modules unreachable, so the resolver discriminates rather than marking everything reachable. -
Tests that fail on the pre-fix code (
git checkout cae1f22a4 -- <the five src/scripts files>, run,git checkout HEAD -- <the same files>): 26 failures:test_cig_builder_ast.py8 (TestImportResolutionx7,test_node_ids_follow_sorted_file_order);analysis/15 (test_breaking_change.py: the async test, the changedtest_each_changed_signature_reaches_each_importerand the three layout cases;test_complexity.py2;test_coupling.pyandtest_dead_code.py,test_read_only.py,test_test_coverage.py: thesrc-layoutandrelative-importcases each);test_codemod_cli.py3 (..._exit_zero_with_json_output,..._print_text_sections,test_breaking_changes_base_reads_the_repo_subdirectory_not_the_toplevel). The three real layouts (src layout, importer sorts before importee, relative imports) are theimport_layoutfixture intests/refactor/codemod/analysis/conftest.py; TST-110-016, -018 and -019 each gained a case over it, plus a coupling and a dead-code case. -
Memory note (corrected in fix round 2; the round-1 text, "+67 MB", came from one sample each and is superseded).
test_memory_guardmeasuresload(..., parallel=True).stats().rss_delta_bytesagainst 3,758,096,384 B (3.5 GiB). The S1 loader already sat at the band; S2's own delta is within the run-to-run noise (about +30 MB in the reviewer's four samples each; see the fix round 2 table). The guard is CLOSED in fix round 2 by reducing RSS, not by touching the band (see below). -
Gates (recorded in the ship-log row below).
-
- Review round 2 (GO except MAJOR-1, against 4f31851c6) → fix round 2
(2026-10-06; code 83e74cbad on
feat/spec-110-completion).- MAJOR-1
test_memory_guard(REQ-110-004; band 3,758,096,384 B). OUTCOME A: the test is green and every sample is under the band.-
Where the memory is (stage RSS in one fresh process,
parallel=True, this worktree, 3226 files, 40.6 MB of source): parse of the forest +3,428 MB (89%, the S1LosslessModuletoken stream plus ast per file, not touched); the decodedsourcesdict +87 MB (non-ASCII files widen thestrto 2-4 bytes per character: 87 MB for 40.6 MB of text); CIG build +330 MB (169,573 nodes, the per-module op logs, oneCIGEdgeobject per edge plus a second tuple per edge for the CSR input, the transpose edge list_CSRIndexmakes inside).tracemallocover the full tree does not finish in 10 minutes under the 3.14t free-threaded allocator hooks, so the profile above is the per-stage RSS split plus the object accounting of the builder; the S2 additions (_pending_importstuples, the per-module import path strings) are a few MB and the resolver's_ImportResolveris dropped whenbuild()returns. -
Reductions applied (all in
_cig_builder_ast.pyandworkspace.py, no behaviour change;commit()untouched): (1)_ForestSources, a lazyMappingover the forest, replaces the eager decoded dict, so no second copy of the tree's text is made (build_cig_astreads text only for a path with no pre-parsed tree); (2) the parallel path frees each module's op log as it is replayed, so the logs and the finished graph are not both live; (3) one(source, target)tuple per edge serves the CSR input and the per-type list, replacing aCIGEdgeobject per edge and a rebuilt tuple list (CIGEdgestays defined in_types.py; the builder was its only user). -
Measured (
load(src, scripts, tests, parallel=True), standalone, fresh process per sample, load average under 4 before each sample, MB):state samples mean min / max base cae1f22a4 3826.7, 3824.8, 3834.6, 3759.2 3811.3 3759.2 / 3834.6 HEAD before, 4f31851c6 3768.3, 3750.5, 3763.9, 3761.4 3761.0 3750.5 / 3768.3 HEAD after, 83e74cbad 3642.5, 3635.7, 3663.4, 3639.3 3645.2 3635.7 / 3663.4 Three more interleaved pairs (HEAD, then after, swapping the two files between samples): HEAD 3768.6 / 3757.4 / 3763.1, after 3632.6 / 3687.7 / 3620.7. Over n=7 each: HEAD before mean 3761.9 (3750.5-3768.6), HEAD after mean 3646.0 (3620.7-3687.7), reduction about 116 MB; the highest sample is 70 MB under the band. The resolver fixes alone (HEAD memory structure plus the round 2 resolver) measured 3766.3 / 3756.7 / 3774.8 against HEAD 3764.9 / 3758.5 / 3768.1, so they cost nothing. A first measurement of the resolver-only state at 3,827.7 MB (n=4) was taken in a different load window and is not reproduced by the interleaved runs: the same code moves by about 70 MB between windows, which is the reviewer's 3,839 MB for HEAD. A window that inflates by 70 MB leaves
HEAD afterat about 3,716 MB, still under the band by about 40 MB. -
Not done (out of the brief's files):
_CSRIndex.__init__builds the transpose edge list as a second full list of new tuples ([(to, frm) for frm, to in edges]), a transient of about one tuple per edge;_csr_index.pyis not in this round's FILES. It is the next lever if the margin has to widen, and the S1 token stream (89% of the delta) is the only lever that moves the floor by hundreds of MB.
-
- MINOR-1
_relative_rootsclimbed past the top package (pkg/m.py: from .. import yboundy.py; Python raises "beyond top-level package"). Fix: a climb above the importing package must land in a directory registered as a package (<dir>/__init__.py), else no roots.test_external_self_and_overshooting_imports_make_no_edgewas false-confidence (nothing existed to bind): it now carries a rootfar.py;test_overshooting_relative_import_does_not_bind_past_the_top_packageandtest_relative_climb_into_an_enclosing_package_still_bindsare new. - MINOR-2 every top-level directory was a root for every importer, so
import logginginsidesrc/pkgcould bindscripts/logging.pyor a rootjson.py. Fix: absolute names insys.stdlib_module_namesnever resolve; an importer inside a package nested below the repo root tries only its own package root, the repo root and the other package roots. The brief said "package importer";scripts/has an__init__.pyhere, and treating it as a package dropped 13 realscripts/toscripts/sibling edges (27 to 14, the probe figure below; the builder's first write-up said 10, which no run reproduces) (a script run from its directory imports_irc_conversationby bare name), so a package directly under the repo root (scripts/,tests/) keeps the top-level directories like any script directory (stated indocs/codemod-analysis.md). Tests:test_stdlib_name_never_binds_to_a_same_named_repo_file,test_package_importer_does_not_bind_into_scripts_or_tests_by_bare_name. - MINOR-3
from A import BtriedA/B.pyunder every root beforeA/__init__.pyunder an earlier root. The loops are swapped (roots outer, names inner);test_from_import_prefers_an_earlier_roots_package_over_a_later_submodule. - MINOR-4
@traces(spec="110", story="US-110-006", reqs=["REQ-110-031"])onTestImportResolutionandtest_node_ids_follow_sorted_file_order(the formanalysis/uses; the spec lists no per-story REQ mapping, andanalysis/ties REQ-110-031 to US-110-006); the newTestLazySourcesclass isUS-110-001/REQ-110-004.reports/rtm-evidence.*untouched. - Tests that fail on the pre-fix code (src file swapped to 4f31851c6 and back): 5 of the 6 resolver tests fail (the overshoot false-confidence test, the new overshoot test, the stdlib test, the bare-name test, the package-over-submodule test); the sixth, the enclosing-package climb, is a guard that passes before and after.
- Edge-count probe (
build_cig_astover every.pyundersrc/,scripts/,tests/; 3226 modules): IMPORTS edges 7,927 before and 7,927 after;src/toscripts/edges 12 before and 12 after (the brief expected 14 and a drop forjanus_swi). The edge SET is identical: this repo has no stdlib-named file for a package module to hit, and no bare name that crossed intoscripts/ortests/, so MINOR-2 and MINOR-3 are guards against layouts this repo does not have today.janus_swistill bindsscripts/_janus_patched/build/lib.linux-x86_64-cpython-314t/janus_swi/__init__.py: that directory is an inferred package root (it holds an__init__.pychain), which is what the rule keeps. The first cut of MINOR-2 (own package root plus repo root only) took tests to src from 4,335 to 1,510 and scripts to scripts from 27 to 14, which is how theorchestrata_ultimatepackage root and thescripts/rule above were found. - Verification:
analysis/+test_cig_builder_ast.py+tests/scripts/test_codemod_cli.py+test_workspace_load.py= 179 passed, 0 failed, 0 skipped (includestest_memory_guard); the remainingtests/refactor/codemod/modules +tests/scripts/test_codemod_fast.py= 880 passed, 1 failed, 0 skipped: the knowntest_daemon_lifecycle.py::TestPidIsCodemodDaemon/procargv race (the P5 carry-over; the failing test varies by run). Coverage (line, this round):_cig_builder_ast.py99% (3 of 374 missed: 720-721, the_extract_annotationexcept branch, and 806, thekeep < 0relative-import guard),workspace.py93%. Gates after the fix:gates.pyALL GATES PASS (exit 0),gate.py runexit 0 immediately after,check-deps --include-tests0,check_spec_authority.py0.
- MAJOR-1
- Review round 3 (GO, against 3e4fe1e6d, 2026-10-06). The reviewer re-ran the
fix-round-2 claims under the authoritative observer plugins (the round had to
wait for the suite to go idle; the monitor was stopped and the reviewer
resumed when the load dropped).
- Memory:
test_memory_guardpeak RSS 3,631 / 3,633 / 3,621 MB over three runs against the 3,758 MB band, a margin of 125 MB at the worst sample; the ~116 MB reduction from fix round 2 is real and repeatable. - Resolver identity:
build_cig_astover every.pyundersrc/,scripts/,tests/(3,226 modules) at 4f31851c6 and at 3e4fe1e6d gives the identical IMPORTS edge SET (7,927 edges), which is the number this repo's edge-count probe above also reports; the resolver fixes change nothing in this tree and are guards for the layouts named in MINOR-A/B. - Tests: the 179-test group (analysis/,
test_cig_builder_ast.py,test_codemod_cli.py,test_workspace_load.py) 179 passed, 0 failed, 0 skipped; the remainingtests/refactor/codemod/modules plustest_codemod_fast.py785 passed, 0 failed, 0 skipped. The builder's "880 passed, 1 failed" figure for that second group is not reproducible from the module list the plan names: the reviewer's count of the same list is 785, andTestPidIsCodemodDaemondid not fail in the reviewer's run. The 880 figure stays in the fix-round-2 record as the builder's own report; the shipped number is 785 + 179 = 964 passed, 0 failed. - Carried items: MINOR-A/B (resolver layout heuristic), the INHERITS = 0 / OVERRIDES = 0 audit, the gitignored-path loader note and the REQ-110-031 retag are backlog items (9) to (12) in the S2 packet record above; none blocks the ship.
- Memory:
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 : 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/, 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 nametophasorinctx.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/lies 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) |