Compare commits

..

No commits in common. "f963e7b6ce4d1435d500ceb9dd22bc75b9665488" and "e90f2f224abac0b47f020c3af2faf85e1c86cdbc" have entirely different histories.

9 changed files with 3 additions and 252 deletions

View File

@ -162,10 +162,6 @@ jobs:
run: uv run python -c "import sys; import tractor; from tractor.ipc._uds import HAS_UDS; assert sys.platform != 'win32' or not HAS_UDS; print('import tractor OK | HAS_UDS=', HAS_UDS)" run: uv run python -c "import sys; import tractor; from tractor.ipc._uds import HAS_UDS; assert sys.platform != 'win32' or not HAS_UDS; print('import tractor OK | HAS_UDS=', HAS_UDS)"
- name: Run tests - name: Run tests
# Actor/PTY scheduling on macOS can fail a different
# timing-sensitive node between otherwise-green runs. Retry
# only that matrix leg; deterministic failures still fail
# after the final attempt.
continue-on-error: ${{ matrix.os == 'windows-latest' }} continue-on-error: ${{ matrix.os == 'windows-latest' }}
run: > run: >
uv run uv run
@ -175,8 +171,6 @@ jobs:
--spawn-backend=${{ matrix.spawn_backend }} --spawn-backend=${{ matrix.spawn_backend }}
--tpt-proto=${{ matrix.tpt_proto }} --tpt-proto=${{ matrix.tpt_proto }}
--capture=fd --capture=fd
--reruns=${{ matrix.os == 'macos-latest' && 2 || 0 }}
--reruns-delay=1
# XXX legacy NOTE XXX # XXX legacy NOTE XXX
# #

View File

@ -1,37 +0,0 @@
---
model: gpt-5.6-sol
service: opencode
session: tractor-addr-unpacking
timestamp: 2026-08-21T05:20:52Z
git_ref: 3690e43a
scope: config
substantive: true
raw_file: 20260821T052052Z_3690e43a_prompt_io.raw.md
---
## Prompt
The human asked for a main-first patch using an off-the-shelf pytest
plugin to cope with tractor's changing macOS CI flakes without mixing
that mitigation into PR #505.
## Response summary
Added `pytest-rerunfailures` to tractor's testing dependencies and
configured the GitHub Actions matrix to retry failures only on macOS.
Linux and Windows remain strict first-attempt runs, while persistent
macOS failures still fail after two visible reruns.
## Files changed
- `.github/workflows/ci.yml` - macOS-only pytest rerun budget.
- `pyproject.toml` - testing plugin dependency and rationale.
- `uv.lock` - resolved `pytest-rerunfailures` package metadata.
## Human edits
The human selected a main-first mitigation after PR #505 failed two
different macOS tests on consecutive runs and required the change to
remain an incremental patch with its own commit plan. The agent
implemented and verified that direction; no direct manual source
edits were observed.

View File

@ -1,25 +0,0 @@
---
model: gpt-5.6-sol
service: opencode
timestamp: 2026-08-21T05:20:52Z
git_ref: 3690e43a
diff_cmd: git diff HEAD~1..HEAD
---
# Raw output - retry flaky macOS CI tests
The human requested an off-the-shelf pytest plugin patch suitable
for landing directly on tractor `main` after PR #505's macOS job
failed two different timing-sensitive tests on consecutive runs.
> `git diff HEAD~1..HEAD -- .github/workflows/ci.yml pyproject.toml uv.lock`
Added the pytest-dev-maintained `pytest-rerunfailures` plugin and
gave only the macOS matrix leg two reruns with a one-second delay.
Linux and Windows receive a zero retry budget; deterministic macOS
failures still fail after the final attempt and reruns remain visible
in pytest output.
The lockfile is current, actionlint passed, all 471 tests collected,
and the four tests covering both observed PR #505 failure areas
passed with the rerun plugin enabled.

View File

@ -1,36 +0,0 @@
---
model: openai/gpt-5.6-sol
service: opencode
session: ses_fd403c9c9ffe625w99Tr0ALQBN
timestamp: 2026-08-25T18:11:02Z
git_ref: 3690e43a
scope: config
substantive: true
raw_file: 20260825T181102Z_3690e43a_prompt_io.raw.md
---
## Prompt
Enforce the 69-column Python source limit through Ruff and record a
follow-up for richer project-specific style checks.
## Response summary
Enabled E501 at 69 columns and documented a later changed-line
token/AST checker for style rules Ruff cannot represent. Isolated the
configuration on a dedicated follow-up branch after measuring the
existing repository lint debt.
## Files changed
- `ruff.toml` - enables 69-column E501 enforcement and records
follow-up lint work.
## Human edits
The human initially selected immediate global enforcement and
explicitly requested the richer-checker TODO. After review exposed
1,548 existing diagnostics, the human directed the work onto an
independent linting branch and deferred landing until incremental
enforcement is implemented. The agent applied the config and transfer;
no direct manual source edits were identified.

View File

@ -1,24 +0,0 @@
---
model: openai/gpt-5.6-sol
service: opencode
timestamp: 2026-08-25T18:11:02Z
git_ref: main
diff_cmd: git diff HEAD~1..HEAD -- ruff.toml
---
## Prompt
Enable Ruff enforcement of the shared 69-column Python source limit in
Modden, Piker, and Tractor. Add a TODO for a later changed-line token/AST
checker covering project rules Ruff cannot express.
## Response
Configured Ruff's formatter/lint line length to 69 and enabled E501. Added a
follow-up TODO for boolean layout, local annotation placement, docstring
quoting and rationale, and symbol-qualified technical prose.
> `git diff HEAD~1..HEAD -- ruff.toml`
The configuration parses successfully. Existing Tractor package/test debt is
1,469 E501 diagnostics; it was reported rather than reformatted implicitly.

View File

@ -1,97 +0,0 @@
# Incremental Python Style Enforcement
## Objective
Enforce the mechanically checkable parts of `/py-codestyle` on new and
changed Python lines without requiring an immediate repository-wide
cleanup. Keep subjective prose guidance in review policy and expose
legacy debt separately from blocking CI.
## Current State
- `ruff.toml` sets the intended 69-column limit and enables `E501`.
- A package-and-test scan reports 1,548 existing violations.
- Ruff can enforce line length, ordinary syntax rules, unused f-string
prefixes, and configured quote style.
- Ruff cannot directly encode several project-specific layout,
docstring, annotation, and technical-prose policies.
The initial configuration is branch scaffolding, not a landable final
state. The implementation must make changed-code enforcement usable
before this branch targets `main`.
## Policy Matrix
Document each `/py-codestyle` rule under one enforcement class:
1. Ruff lint rule, enabled directly when the repository is clean.
2. Ruff formatter setting, used for intentionally formatted files.
3. Deterministic token or AST check, enforced on changed lines.
4. Review-only guidance where automation would produce false positives.
Start with native checks for `E501`, `F541`, quote style, import and
syntax errors. Use custom checks for exact docstring delimiters and
shape, multiline string construction, double-newline source layout,
f-string continuation consistency, local annotation placement, and
boolean-expression layout. Keep symbol-qualified technical prose and
regression-test rationale as review guidance unless a low-noise warning
can be demonstrated.
## Changed-Line Harness
Add `scripts/check_py_codestyle.py` with these responsibilities:
- Read a base revision and collect added line ranges from `git diff
--unified=0`.
- Treat every line in an added Python file as changed.
- Run Ruff with JSON output and the incremental native-rule set.
- Report only diagnostics intersecting added line ranges.
- Run token/AST checks and apply the same changed-line filter.
- Return a nonzero status only for changed-code violations.
- Offer a separate nonblocking full-tree debt-report mode.
Keep `E501` out of the default global Ruff selection until the legacy
count reaches zero. The harness should request it explicitly so normal
repository lint remains useful during migration.
## Verification
Add focused checker tests covering:
- diff range parsing, deleted lines, renames, and new files;
- 69-column boundaries with indentation and string syntax;
- compliant and noncompliant docstring delimiters and closing shape;
- f-string continuation and double-newline source layout;
- boolean layout and local annotation placement;
- diagnostics on untouched legacy lines being ignored;
- diagnostics on newly touched legacy lines becoming blocking.
Run the checker against a fixture base and against the branch diff. Run
the existing Ruff checks without incremental rules to prove the normal
lint path remains usable.
## CI Integration
Add a dedicated CI step that derives the pull-request base commit from
the event payload and invokes the changed-line harness. Preserve a local
`--base main` mode for developers. Emit normal file, line, column, and
rule identifiers so forge annotations remain navigable.
Publish the full-tree debt count as nonblocking output. Do not hide or
silently rewrite existing source violations.
## Commit Boundaries
1. Record the 69-column policy scaffold and provenance.
2. Add the changed-line Ruff harness and its tests.
3. Add deterministic token/AST policy checks and fixtures.
4. Wire the harness into CI and document local usage.
5. Enable native rules globally only after their legacy counts reach
zero, using separate cleanup commits where needed.
## Deferred
Type-checking migration belongs in a separate branch. It should use the
same incremental principle: establish the tool configuration and debt
inventory, gate new or changed code, publish nonblocking full-tree debt,
and tighten global enforcement as annotations and defects are repaired.

View File

@ -100,9 +100,6 @@ testing = [
# cleanup utility (xplatform `Process.memory_maps`, # cleanup utility (xplatform `Process.memory_maps`,
# `Process.open_files`). # `Process.open_files`).
"psutil>=7.0.0", "psutil>=7.0.0",
# rerun timing-sensitive macOS CI nodes without hiding a
# deterministic failure after the final attempt.
"pytest-rerunfailures>=16.6,<17",
] ]
repl = [ repl = [
"pyperclip>=1.9.0", "pyperclip>=1.9.0",

View File

@ -31,8 +31,8 @@ exclude = [
"venv", "venv",
] ]
# Project source style limit. # Same as Black.
line-length = 69 line-length = 88
indent-width = 4 indent-width = 4
# assume latest minor cpython # assume latest minor cpython
@ -42,15 +42,11 @@ target-version = "py313"
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default. # McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "E501", "F"] select = ["E4", "E7", "E9", "F"]
ignore = [ ignore = [
'E402', # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file/ 'E402', # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file/
] ]
# TODO: add a changed-line token/AST checker for py-codestyle rules
# Ruff cannot express: boolean layout, local annotation placement,
# docstring quoting/rationale, and symbol-qualified technical prose.
# Allow fix for all enabled rules (when `--fix`) is provided. # Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"] fixable = ["ALL"]
unfixable = [] unfixable = []

17
uv.lock
View File

@ -782,19 +782,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8b/5a/ba30a81239b909821b3153e303e7def45178bf353da4f72380e6c5e8793b/pytest-9.1.0-py3-none-any.whl", hash = "sha256:8ebb0e7888bdf2bdfc602ec51f8f62d50200af37356c74e503c79a94f5c81f32", size = 386453, upload-time = "2026-06-13T18:52:44.045Z" }, { url = "https://files.pythonhosted.org/packages/8b/5a/ba30a81239b909821b3153e303e7def45178bf353da4f72380e6c5e8793b/pytest-9.1.0-py3-none-any.whl", hash = "sha256:8ebb0e7888bdf2bdfc602ec51f8f62d50200af37356c74e503c79a94f5c81f32", size = 386453, upload-time = "2026-06-13T18:52:44.045Z" },
] ]
[[package]]
name = "pytest-rerunfailures"
version = "16.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "packaging" },
{ name = "pytest" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ed/63/0114e45d4b2fcd5f6297dac655c067b47de28be4d33e088f200f0f2c4c28/pytest_rerunfailures-16.6.tar.gz", hash = "sha256:29dbfee46f542073c888e0ed4e81c51e15b9096f49a299eb1a759629c601684a", size = 42806, upload-time = "2026-08-17T07:11:00.447Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5d/5e/1e994889673d7a0da11651f17ef789b6c83bfe349f29f871873dd3802445/pytest_rerunfailures-16.6-py3-none-any.whl", hash = "sha256:6af2d1ebd6e5cb79666ac408942cd6a0672a49fefd8523664770718560795e13", size = 19137, upload-time = "2026-08-17T07:10:59.121Z" },
]
[[package]] [[package]]
name = "pytest-timeout" name = "pytest-timeout"
version = "2.4.0" version = "2.4.0"
@ -1144,7 +1131,6 @@ dev = [
{ name = "psutil" }, { name = "psutil" },
{ name = "pyperclip" }, { name = "pyperclip" },
{ name = "pytest" }, { name = "pytest" },
{ name = "pytest-rerunfailures" },
{ name = "pytest-timeout" }, { name = "pytest-timeout" },
{ name = "stackscope" }, { name = "stackscope" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
@ -1184,7 +1170,6 @@ testing = [
{ name = "pexpect" }, { name = "pexpect" },
{ name = "psutil" }, { name = "psutil" },
{ name = "pytest" }, { name = "pytest" },
{ name = "pytest-rerunfailures" },
{ name = "pytest-timeout" }, { name = "pytest-timeout" },
] ]
@ -1210,7 +1195,6 @@ dev = [
{ name = "psutil", specifier = ">=7.0.0" }, { name = "psutil", specifier = ">=7.0.0" },
{ name = "pyperclip", specifier = ">=1.9.0" }, { name = "pyperclip", specifier = ">=1.9.0" },
{ name = "pytest", specifier = ">=9.0.3" }, { name = "pytest", specifier = ">=9.0.3" },
{ name = "pytest-rerunfailures", specifier = ">=16.6,<17" },
{ name = "pytest-timeout", specifier = ">=2.3" }, { name = "pytest-timeout", specifier = ">=2.3" },
{ name = "stackscope", specifier = ">=0.2.2,<0.3" }, { name = "stackscope", specifier = ">=0.2.2,<0.3" },
{ name = "typing-extensions", specifier = ">=4.14.1" }, { name = "typing-extensions", specifier = ">=4.14.1" },
@ -1242,7 +1226,6 @@ testing = [
{ name = "pexpect", specifier = ">=4.9.0,<5" }, { name = "pexpect", specifier = ">=4.9.0,<5" },
{ name = "psutil", specifier = ">=7.0.0" }, { name = "psutil", specifier = ">=7.0.0" },
{ name = "pytest", specifier = ">=9.0.3" }, { name = "pytest", specifier = ">=9.0.3" },
{ name = "pytest-rerunfailures", specifier = ">=16.6,<17" },
{ name = "pytest-timeout", specifier = ">=2.3" }, { name = "pytest-timeout", specifier = ">=2.3" },
] ]