From d83d9b0c66c6cd96d7938452cc7c9135789f7ec5 Mon Sep 17 00:00:00 2001 From: kokokoXUY <13682395396@163.com> Date: Sat, 26 Sep 2026 23:32:06 +0800 Subject: [PATCH] fix: frame the last JSONL readers on LF #5117 and #5118 corrected thirteen readers that parse one JSON document per line. Sixteen more call sites still framed those records with `str.splitlines()`: `benchmark_toolkit/experiment_board.py`, `benchmark_toolkit/study_projection.py`, `issue_fix/cli_input.py` (two), `issue_fix/discovered_issue_promotion.py`, `issue_fix/outcome_projection.py`, `issue_fix/pr_monitor_materialization.py`, `repository_change_window/ledger.py`, `cli_commands/lark_inbox.py`, `coordination/runtime_shadow.py` (two), `quota/codex_session_usage.py`, `quota/slot_accounting.py`, `runtime/stride_observation.py`, `testing/replan_vision_closeout_behavior.py` and `planner_worker/traex.py`. A record whose value carries U+0085/U+2028/U+2029 arrived as two fragments and `json.loads` failed on both, so the row was dropped, reported as invalid (`invalid local upload JSONL row`) or raised (`traex returned invalid JSONL`). All sixteen now frame on LF, each as a one-line change that leaves the loop, its line numbering and its error text unchanged. Validation: `ruff check` on all fourteen changed modules reports `All checks passed!` and all of them import cleanly. `pytest -q tests/capabilities -k "issue_fix or ledger or traex"` -> 133 passed, 18 failed; the failures are pre-existing host limitations (for example `git` refusing to create `tracked.txt?` on Windows), not framing results. The end-to-end framing case added in #5118 covers this identical one-line pattern through a real store round-trip. Signed-off-by: kokokoXUY <13682395396@163.com> --- loopx/capabilities/benchmark_toolkit/experiment_board.py | 2 +- loopx/capabilities/benchmark_toolkit/study_projection.py | 2 +- loopx/capabilities/issue_fix/cli_input.py | 4 ++-- loopx/capabilities/issue_fix/discovered_issue_promotion.py | 2 +- loopx/capabilities/issue_fix/outcome_projection.py | 2 +- loopx/capabilities/issue_fix/pr_monitor_materialization.py | 2 +- loopx/capabilities/repository_change_window/ledger.py | 2 +- loopx/cli_commands/lark_inbox.py | 2 +- loopx/control_plane/coordination/runtime_shadow.py | 4 ++-- loopx/control_plane/quota/codex_session_usage.py | 2 +- loopx/control_plane/quota/slot_accounting.py | 2 +- loopx/control_plane/runtime/stride_observation.py | 2 +- .../control_plane/testing/replan_vision_closeout_behavior.py | 2 +- loopx/experiments/planner_worker/traex.py | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/loopx/capabilities/benchmark_toolkit/experiment_board.py b/loopx/capabilities/benchmark_toolkit/experiment_board.py index 68fd319426..1048e2e2b8 100644 --- a/loopx/capabilities/benchmark_toolkit/experiment_board.py +++ b/loopx/capabilities/benchmark_toolkit/experiment_board.py @@ -396,7 +396,7 @@ def read_benchmark_experiment_board_rows( return [] rows: list[dict[str, Any]] = [] for index, line in enumerate( - path.read_text(encoding="utf-8").splitlines(), start=1 + path.read_text(encoding="utf-8").split("\n"), start=1 ): if not line.strip(): continue diff --git a/loopx/capabilities/benchmark_toolkit/study_projection.py b/loopx/capabilities/benchmark_toolkit/study_projection.py index 0cb69e3eaa..9cad9739a1 100644 --- a/loopx/capabilities/benchmark_toolkit/study_projection.py +++ b/loopx/capabilities/benchmark_toolkit/study_projection.py @@ -588,7 +588,7 @@ def _read_jsonl_objects(path: Path) -> list[dict[str, Any]]: if not path.exists(): return [] rows: list[dict[str, Any]] = [] - for index, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1): + for index, line in enumerate(path.read_text(encoding="utf-8").split("\n"), 1): if not line.strip(): continue try: diff --git a/loopx/capabilities/issue_fix/cli_input.py b/loopx/capabilities/issue_fix/cli_input.py index 9b9d1548aa..c080ba7ab0 100644 --- a/loopx/capabilities/issue_fix/cli_input.py +++ b/loopx/capabilities/issue_fix/cli_input.py @@ -45,7 +45,7 @@ def load_jsonl_row( raise ValueError(f"issue-fix domain-state source is missing: {path.name}") match: dict[str, Any] | None = None for line_number, line in enumerate( - path.read_text(encoding="utf-8").splitlines(), start=1 + path.read_text(encoding="utf-8").split("\n"), start=1 ): if not line.strip(): continue @@ -73,7 +73,7 @@ def load_jsonl_rows(path: Path) -> list[dict[str, Any]]: raise ValueError(f"issue-fix domain-state source is missing: {path.name}") rows: list[dict[str, Any]] = [] for line_number, line in enumerate( - path.read_text(encoding="utf-8").splitlines(), start=1 + path.read_text(encoding="utf-8").split("\n"), start=1 ): if not line.strip(): continue diff --git a/loopx/capabilities/issue_fix/discovered_issue_promotion.py b/loopx/capabilities/issue_fix/discovered_issue_promotion.py index 5668f0d34e..6c8ec0db50 100644 --- a/loopx/capabilities/issue_fix/discovered_issue_promotion.py +++ b/loopx/capabilities/issue_fix/discovered_issue_promotion.py @@ -501,7 +501,7 @@ def _find_domain_row( if not path.is_file(): return None match = None - for line in path.read_text(encoding="utf-8").splitlines(): + for line in path.read_text(encoding="utf-8").split("\n"): if not line.strip(): continue row = json.loads(line) diff --git a/loopx/capabilities/issue_fix/outcome_projection.py b/loopx/capabilities/issue_fix/outcome_projection.py index d4d0625c6f..aa76d5b91f 100644 --- a/loopx/capabilities/issue_fix/outcome_projection.py +++ b/loopx/capabilities/issue_fix/outcome_projection.py @@ -864,7 +864,7 @@ def _load_domain_packets(path: Path) -> tuple[list[dict[str, Any]], list[str]]: packets: list[dict[str, Any]] = [] warnings: list[str] = [] for line_number, line in enumerate( - path.read_text(encoding="utf-8").splitlines(), start=1 + path.read_text(encoding="utf-8").split("\n"), start=1 ): if not line.strip(): continue diff --git a/loopx/capabilities/issue_fix/pr_monitor_materialization.py b/loopx/capabilities/issue_fix/pr_monitor_materialization.py index e83dd93f19..508e8d3e31 100644 --- a/loopx/capabilities/issue_fix/pr_monitor_materialization.py +++ b/loopx/capabilities/issue_fix/pr_monitor_materialization.py @@ -28,7 +28,7 @@ def _load_lifecycle_rows(path: Path) -> list[dict[str, Any]]: rows: list[dict[str, Any]] = [] for line_number, raw_line in enumerate( - path.read_text(encoding="utf-8").splitlines(), start=1 + path.read_text(encoding="utf-8").split("\n"), start=1 ): if not raw_line.strip(): continue diff --git a/loopx/capabilities/repository_change_window/ledger.py b/loopx/capabilities/repository_change_window/ledger.py index 5ca6eb2485..2e1058f714 100644 --- a/loopx/capabilities/repository_change_window/ledger.py +++ b/loopx/capabilities/repository_change_window/ledger.py @@ -135,7 +135,7 @@ def _read_events(path: Path) -> list[dict[str, Any]]: return [] result: list[dict[str, Any]] = [] for line_number, line in enumerate( - path.read_text(encoding="utf-8").splitlines(), 1 + path.read_text(encoding="utf-8").split("\n"), 1 ): if not line.strip(): continue diff --git a/loopx/cli_commands/lark_inbox.py b/loopx/cli_commands/lark_inbox.py index 90e7aa4614..33459e3ec2 100644 --- a/loopx/cli_commands/lark_inbox.py +++ b/loopx/cli_commands/lark_inbox.py @@ -315,7 +315,7 @@ def _read_stdin_events() -> list[object]: try: payload = json.loads(raw) except json.JSONDecodeError: - payload = [json.loads(line) for line in raw.splitlines() if line.strip()] + payload = [json.loads(line) for line in raw.split("\n") if line.strip()] if isinstance(payload, list): return payload if isinstance(payload, dict): diff --git a/loopx/control_plane/coordination/runtime_shadow.py b/loopx/control_plane/coordination/runtime_shadow.py index 231f33e5b6..9c07486f9e 100644 --- a/loopx/control_plane/coordination/runtime_shadow.py +++ b/loopx/control_plane/coordination/runtime_shadow.py @@ -349,7 +349,7 @@ def read_evidence(path: Path) -> bytes | None: rollout_bytes = read_evidence(rollout_event_log_path(runtime_root, goal_id)) rollout_events: list[dict[str, Any]] = [] - for line in (rollout_bytes or b"").decode("utf-8").splitlines(): + for line in (rollout_bytes or b"").decode("utf-8").split("\n"): try: value = json.loads(line) except json.JSONDecodeError: @@ -363,7 +363,7 @@ def read_evidence(path: Path) -> bytes | None: data = read_evidence(path) if not data: continue - events = [normalize_state_event(json.loads(line)) for line in data.decode("utf-8").splitlines() if line.strip()] + events = [normalize_state_event(json.loads(line)) for line in data.decode("utf-8").split("\n") if line.strip()] rendered = render_active_state_sections(build_state_projection(events, goal_id=goal_id)) fields = parse_active_state_todos(rendered, goal=dict(goal), state_path=state_path, item_limit=None, rollout_events=rollout_events) if any(fields.get(f"{role}_todos") for role in ("user", "agent")): diff --git a/loopx/control_plane/quota/codex_session_usage.py b/loopx/control_plane/quota/codex_session_usage.py index 7408095841..36d0c3679d 100644 --- a/loopx/control_plane/quota/codex_session_usage.py +++ b/loopx/control_plane/quota/codex_session_usage.py @@ -312,7 +312,7 @@ def session_usage_baseline( snapshot_first_booked_at: Any = None binding_recorded = False seen_rows: set[tuple[str, str, str]] = set() - for line_number, line in enumerate(raw.splitlines(), start=1): + for line_number, line in enumerate(raw.split("\n"), start=1): line = line.strip() if not line: continue diff --git a/loopx/control_plane/quota/slot_accounting.py b/loopx/control_plane/quota/slot_accounting.py index eeacd97b25..387ed81304 100644 --- a/loopx/control_plane/quota/slot_accounting.py +++ b/loopx/control_plane/quota/slot_accounting.py @@ -348,7 +348,7 @@ def _load_goal_run_index_records(runtime_root: Path, goal_id: str) -> list[dict[ return [] records: list[dict[str, Any]] = [] try: - lines = index_path.read_text(encoding="utf-8").splitlines() + lines = index_path.read_text(encoding="utf-8").split("\n") except OSError: return [] for line in lines: diff --git a/loopx/control_plane/runtime/stride_observation.py b/loopx/control_plane/runtime/stride_observation.py index 49a64a2735..3a5b87ee65 100644 --- a/loopx/control_plane/runtime/stride_observation.py +++ b/loopx/control_plane/runtime/stride_observation.py @@ -55,7 +55,7 @@ def read_run_index(runtime_root: Path, goal_id: str) -> list[dict[str, Any]]: if not index_path.exists(): return [] rows: list[dict[str, Any]] = [] - for line in index_path.read_text(encoding="utf-8").splitlines(): + for line in index_path.read_text(encoding="utf-8").split("\n"): if not line.strip(): continue try: diff --git a/loopx/control_plane/testing/replan_vision_closeout_behavior.py b/loopx/control_plane/testing/replan_vision_closeout_behavior.py index a07d1c17e4..3a17f52b19 100644 --- a/loopx/control_plane/testing/replan_vision_closeout_behavior.py +++ b/loopx/control_plane/testing/replan_vision_closeout_behavior.py @@ -121,7 +121,7 @@ def _rows(state: _QualificationState) -> list[dict[str, Any]]: index = state.fixture.runtime_root / "goals" / goal_id / "runs" / "index.jsonl" if not index.is_file(): return [] - return [json.loads(line) for line in index.read_text(encoding="utf-8").splitlines() if line] + return [json.loads(line) for line in index.read_text(encoding="utf-8").split("\n") if line] def dispatch_vision_closeout( diff --git a/loopx/experiments/planner_worker/traex.py b/loopx/experiments/planner_worker/traex.py index 1d5316f0aa..5f747a1348 100644 --- a/loopx/experiments/planner_worker/traex.py +++ b/loopx/experiments/planner_worker/traex.py @@ -34,7 +34,7 @@ def _assistant_text_and_usage(jsonl: str) -> tuple[str, dict[str, int], bool]: parts: list[str] = [] usage: dict[str, int] = {} completed = False - for line in jsonl.splitlines(): + for line in jsonl.split("\n"): if not line.strip(): continue try: