Skip to content

Commit d98911a

Browse files
committed
Enforce the 120-column limit and keep test runs out of the shared log
CLAUDE.md says ruff rejects lines over 120 characters, but the repo had no ruff configuration, so CI ran the default rules without E501 and 67 lines were over. pyproject now selects E501 at 120 and every flagged line is back under it; suppression markers stay on the line the analyzers report, with the prose moved to a comment above. 31 of those lines were in the generated IDE stub, which turned out to list 199 of the 739 executor commands: the generator now wraps long signatures, the stub is regenerated, and a test compares its command set with the executor. This repo's own tests were also writing the shared ~/.je_auto_control log. The handler now reads JE_AUTOCONTROL_LOG_FILE when it opens the file, so test/conftest.py can redirect it even though the pytest11 plugin imports the package first.
1 parent 329cea3 commit d98911a

36 files changed

Lines changed: 3080 additions & 153 deletions

‎CHANGELOG.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ it shipped into a `## [x.y.z] - date` section of their own; the tag's
2929
imported it — including every pytest run on a machine where it is installed,
3030
through the `pytest11` plugin — left a log wherever it started. The file is
3131
now `~/.je_auto_control/logs/AutoControlGUI.log`, or whatever
32-
`JE_AUTOCONTROL_LOG_FILE` names (`os.devnull` turns it off). Because every
32+
`JE_AUTOCONTROL_LOG_FILE` names when the file is first opened, so a
33+
`conftest.py` can still redirect it after the plugin imported the package
34+
(`os.devnull` turns it off). Because every
3335
process shares it, lines carry the process id (`time | pid | logger | level
3436
| message`), and instead of growing without limit it is moved to `.1` once
3537
past 10 MB, at the moment a process opens it. The file is opened on the

‎Progress.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,22 @@ DEBUG 都會流到 root 的 handler(用了 `basicConfig` 的程式會被灌爆
172172

173173
---
174174

175+
## 測試會寫進真正的 `~/.je_auto_control/`
176+
177+
`TODO` — `test/conftest.py` 只把記錄檔導到暫存目錄,其他每使用者狀態沒有
178+
179+
2026-09-23 跑整套測試的時段,家目錄的 `audit.db`(遠端桌面的稽核鏈)、`address_book.json`、
180+
`quarantine.json`、`run_history.sqlite` 都被改過,`artifacts/` 累積了 419 張錯誤截圖(日期
181+
對得上每一天的開發測試)。這些預設路徑大多在**呼叫時**才算 `Path.home()`(`audit_log.py:41`、
182+
`address_book.py:31`、`quarantine/store.py:39`、`run_history/history_store.py:81`、
183+
`run_history/artifact_manager.py:20`),所以在 `test/conftest.py` 把 `HOME`/`USERPROFILE`
184+
指到每次一個的暫存目錄就擋得住;**import 時就算好的**常數(`ab_locator/store.py:70`、
185+
`cost_telemetry/store.py:57`、`action_signing/{cipher,signer}.py`、`remote_desktop/fingerprint.py`、
186+
`host_service.py:36`、`webrtc_files.py:34`)擋不住,因為 pytest11 外掛比 conftest 早 import
187+
整個套件——要先確認測試有沒有碰到它們,碰到就改成呼叫時才算。
188+
189+
---
190+
175191
## libei 的 `ei_unref` 在半開交握上會 SIGSEGV
176192

177193
`BLOCKED` — 上游(libei 1.3.901)

‎architecture.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ Moving that WebRunner module breaks the bridge.
142142
`je_open_cv` and `mss` off the import path.
143143
- `utils/logging/logging_instance.py` sets the root logger to DEBUG and attaches a file handler at import, but the
144144
handler opens its file on the first record, and nothing logs during the import: importing writes no file at all.
145-
The file is `$JE_AUTOCONTROL_LOG_FILE` if set (a relative path resolves against the cwd at import), else
145+
The file is `$JE_AUTOCONTROL_LOG_FILE` as read when the file is opened (so a `conftest.py` can still set it after
146+
the `pytest11` plugin imported the package; a relative path resolves against the cwd then), else
146147
`~/.je_auto_control/logs/AutoControlGUI.log`, shared by every process: appended to, rotated to `.1` past 10 MB
147148
only when a process opens it, and swapped for `os.devnull` with one `RuntimeWarning` when it cannot be opened.
148149
Consumers that must keep the log out of a shared file (a test suite) set the variable before importing;

‎architecture_explore.md‎

Lines changed: 43 additions & 43 deletions
Large diffs are not rendered by default.

‎docs/updates/2026-09.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,19 @@ Index and query commands: [README.md](README.md). New entries go at the end.
160160
- **Result / numbers**: these three calls were the source of all 13 warnings in the last full headless run (8,166 passed). `-k "color_stats or perceptual or dedup or hash or facade_import" -W error::DeprecationWarning`: 76 passed, 3 skipped. Also found the local `.venv` on Pillow 12.2.0 (the version with the 13 CVEs) despite the pin, and reinstalled 12.3.0.
161161
- **Files**: `je_auto_control/utils/color_stats/color_stats.py`, `je_auto_control/utils/image_dedup/perceptual_hash.py`.
162162
- **Open items**: none.
163+
164+
## U-20260923-05 · 2026-09-23 · Line limit enforced by ruff; stub regenerated (199 → 739) · #done #quality #typing
165+
166+
- **What**: `CLAUDE.md` said the 120-character line limit was the one limit CI rejects (through `ruff`). It was not: the repo had no ruff configuration, so `ruff check je_auto_control/` ran the default rule set (`E4`, `E7`, `E9`, `F`), which has no `E501`, and 67 lines were over 120. `pyproject.toml` now sets `[tool.ruff] line-length = 120` with `extend-select = ["E501"]`, and every flagged line is back under it. Ruff's own rule still exempts a line that ends in a pragma (`# noqa`, `# nosec`), since a marker cannot move.
167+
- **The generated stub**: 31 of the 67 were in `je_auto_control/actions.pyi`, the IDE stub `utils/stubs/generator.py` writes. Regenerating it showed it was far out of date: **199 of 739** executor commands, several with old signatures (`AC_a11y_click` without `window_title`/`contains`). The generator now puts one parameter per line when a `def` line would exceed `MAX_LINE_LENGTH` (120), splitting only at top-level commas so `Dict[str, Any]` stays whole, and the stub is regenerated with it (739 signatures, no line over 120). A test now fails when the stub's command set differs from `executor.event_dict`; names only, because annotations render differently across Python versions (3.14 prints `typing.Union` as `X | Y`).
168+
- **The other 36 lines**: most carried a `NOSONAR` or `nosemgrep` marker followed by a paragraph of justification. The markers stay on the line the analyzer reports (Codacy honours `nosemgrep` only there, and `NOSONAR` only works same-line) and the prose moved to a comment directly above, with `# reason: see above` where the rule calls for an inline reason. The rest were long strings (three UI strings each in the English and Japanese catalogues, one error message), imports and `except` tuples, wrapped with no change in value. `diagnostics.py` imports `import_module` directly so its marked line fits; `xml_file.py` parenthesises one import so its marker stays on the statement's first line.
169+
- **Result / numbers**: `ruff check je_auto_control/` clean with E501 at 120; `test_stub_generator.py` 15 → 19 tests. The `CLAUDE.md` sentence is now true, so it stays as written.
170+
- **Files**: `pyproject.toml`, `je_auto_control/utils/stubs/generator.py`, `je_auto_control/actions.pyi`, `test/unit_test/headless/test_stub_generator.py`, 22 modules for wrapped lines (`gui/language_wrapper/{english,japanese}.py`, `gui/remote_desktop/{webrtc_known_hosts,webrtc_panel}.py`, `gui/usb_browser_tab.py`, `gui/usb_passthrough_prompt.py`, `utils/admin/admin_client.py`, `utils/agent/backends/openai.py`, `utils/callback/callback_function_executor.py`, `utils/clipboard/clipboard.py`, `utils/diagnostics/diagnostics.py`, `utils/exception/exception_tags.py`, `utils/remote_desktop/{host,viewer,webrtc_host,webrtc_stats}.py`, `utils/test_suite/reports.py`, `utils/usb/passthrough/winusb_backend.py`, `utils/usbip/libusb_backend.py`, `utils/vision/backends/openai_backend.py`, `utils/xml/xml_file/xml_file.py`, `wrapper/auto_control_{keyboard,record}.py`), `architecture_explore.md` (figures).
171+
- **Open items**: none.
172+
173+
## U-20260923-06 · 2026-09-23 · Test runs no longer write the shared package log · #incident #logging #testing
174+
175+
- **What**: Reported by the Jeffrey_RPA session an hour after U-20260923-01: this repo's own test suite was writing into the new shared `~/.je_auto_control/logs/AutoControlGUI.log` (5,360 lines by 00:38, all of them from pytest processes — this suite's runs plus one other repo's run through the `pytest11` plugin), the same leak Jeffrey_RPA's repo-root file had and a file its bot will append to after its next restart. A `conftest.py` cannot set `JE_AUTOCONTROL_LOG_FILE` early enough if the handler resolves it at construction, because the plugin imports the package before any conftest runs. The package handler now re-reads `default_log_file()` each time it opens the file (it opens on the first record), and the new `test/conftest.py` overwrites the variable with `<tempdir>/je_auto_control_pytest/AutoControlGUI.log` for every test directory. The polluted file was deleted after checking every writer pid was a pytest process.
176+
- **Result / numbers**: two tests in `test_logging_location.py` (15 now): a delayed handler built before the variable is set writes to the path set afterwards, and the running suite's `default_log_file()` is not the shared file.
177+
- **Files**: `je_auto_control/utils/logging/logging_instance.py`, `test/conftest.py` (new), `test/unit_test/headless/test_logging_location.py`, `architecture.md` (§6 import-time contracts), `CHANGELOG.md`.
178+
- **Open items**: none for the log. The same suite also writes real per-user state (`audit.db`, `address_book.json`, `quarantine.json`, `run_history.sqlite`, `artifacts/`) under `~/.je_auto_control/`; see `Progress.md`.

‎docs/updates/README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ In the same commit: delete the item from `Progress.md`, add a `#done` entry here
5858

5959
| ID | Date | Title | Tags | Batch |
6060
|---|---|---|---|---|
61+
| U-20260923-06 | 2026-09-23 | Test runs no longer write the shared package log | #incident #logging #testing | [2026-09](2026-09.md) |
62+
| U-20260923-05 | 2026-09-23 | Line limit enforced by ruff; stub regenerated (199 → 739) | #done #quality #typing | [2026-09](2026-09.md) |
6163
| U-20260923-04 | 2026-09-23 | Pillow getdata → get_flattened_data (removed in Pillow 14) | #migration #deps | [2026-09](2026-09.md) |
6264
| U-20260923-03 | 2026-09-23 | Every swallowing broad except says why; AST gate in CI | #done #quality | [2026-09](2026-09.md) |
6365
| U-20260923-02 | 2026-09-23 | USB watcher: a stopped (not superseded) run still primes | #incident #usb #ci | [2026-09](2026-09.md) |
@@ -109,7 +111,7 @@ In the same commit: delete the item from `Progress.md`, add a `#done` entry here
109111

110112
| File | Period | Entries |
111113
|---|---|---:|
112-
| [2026-09.md](2026-09.md) | 2026-09 | 20 |
114+
| [2026-09.md](2026-09.md) | 2026-09 | 22 |
113115
| [2026-08-f.md](2026-08-f.md) | 2026-08 | 1 |
114116
| [2026-08-e.md](2026-08-e.md) | 2026-08 | 2 |
115117
| [2026-08-d.md](2026-08-d.md) | 2026-08 | 2 |

0 commit comments

Comments
 (0)