---
model: claude-opus-4-7[1m]
service: claude
timestamp: 2026-04-17T12:44:37Z
git_ref: 5cd6df5
diff_cmd: git diff 5cd6df5~1..5cd6df5
---

Code generated in this turn was committed verbatim as
`5cd6df58` ("Add `'subint'` spawn backend scaffold
(#379)"). Per diff-ref mode, per-file code is captured
via the pointers below, each followed by a prose
summary. Non-code output (sanity-check results,
design rationale) is included verbatim.

## Per-file generated content

### `tractor/spawn/_subint.py` (new, 100 lines)

> `git diff 5cd6df5~1..5cd6df5 -- tractor/spawn/_subint.py`

New scaffolding module for the PEP 734 subinterpreter
backend. Contents:
- AGPL header + module docstring (describes backend
  intent, 3.14+ availability gate, and explicit
  "SCAFFOLDING STUB" status pointing at issue #379).
- Top-level `try/except ImportError` wrapping
  `from concurrent import interpreters as
  _interpreters` → sets module-global
  `_has_subints: bool`. This lets the registry stay
  introspectable on py<3.14 while spawn-time still
  fails cleanly.
- `subint_proc()` coroutine with signature matching
  `trio_proc`/`mp_proc` exactly (same param names,
  defaults, and `TaskStatus[Portal]` typing) —
  intentional so Phase B.2 can drop the impl in
  without touching `_methods` or changing call-site
  binding.
- Body raises `RuntimeError` on py<3.14 (with
  `sys.version` printed) or `NotImplementedError`
  with issue-#379 URL on py≥3.14.

### `tractor/spawn/_spawn.py` (modified, +15 LOC)

> `git diff 5cd6df5~1..5cd6df5 -- tractor/spawn/_spawn.py`

- `import sys` re-added (pruned during Phase A, now
  needed again for the py-version string in the
  `'subint'` gate-error).
- `SpawnMethodKey = Literal[...]` grows `'subint'` as
  the 4th member, with inline comment `# py3.14+ via
  `concurrent.interpreters` (PEP 734)`.
- `try_set_start_method()` match-block grows a new
  `case 'subint':` arm that imports
  `from ._subint import _has_subints` lazily and
  raises `RuntimeError` with a multi-line gate msg
  if unavailable.
- Bottom-of-module late-import section grows
  `from ._subint import subint_proc` alongside the
  existing `_trio` / `_mp` imports.
- `_methods` dict grows `'subint': subint_proc`.

### `tractor/_testing/pytest.py` (modified, +8 LOC)

> `git diff 5cd6df5~1..5cd6df5 -- tractor/_testing/pytest.py`

`pytest_configure()` wraps the
`try_set_start_method(backend)` call in a
`try/except RuntimeError` that re-raises as
`pytest.UsageError(str(err))`. Rationale: the gate
error on py<3.14 is legitimately a configuration
problem, not a test failure, so pytest's UsageError
path (exit code 4) gives a clean single-line banner
instead of a traceback.

### `pyproject.toml` (modified, +2 / -1)

> `git diff 5cd6df5~1..5cd6df5 -- pyproject.toml`

- `requires-python` pin relaxed `>=3.12, <3.14` →
  `>=3.12, <3.15` to admit 3.14 as a valid target.
- Added `"Programming Language :: Python :: 3.14"`
  to the trove classifiers.

## Non-code output (verbatim)

### Design choices captured in the prior turn

(Previously confirmed by the user on April 17 in this
session — relevant excerpts captured here for
provenance since they drove the shape of the impl):

1. **Python pin**: `<3.15` + feature-gate the subint
   backend at spawn time — user answered option (a)
   from the design triage.
2. **Deferred `fork()`-via-subint hack** from issue
   #379's "Our own thoughts" section.
3. **Phase B phasing**: user approved the B.1 / B.2 /
   B.3 / B.4 breakdown — this commit is strictly B.1
   (scaffolding only, no spawn-flow impl).
4. **Option (B) worktree strategy**: new worktree
   branched from `wkt/spawn_modularize`. *(Amended by
   user at runtime: user switched the existing
   `spawn_modularize` worktree to the
   `subint_spawner_backend` branch instead.)*

### Sanity-check output (verbatim terminal excerpts)

Registry / feature-gate verification on py3.13:
```
SpawnMethodKey values: ('trio', 'mp_spawn',
                       'mp_forkserver', 'subint')
_methods keys: ['trio', 'mp_spawn',
                'mp_forkserver', 'subint']
_has_subints: False (py version: (3, 13) )
[expected] RuntimeError: The 'subint' spawn backend
requires Python 3.14+ (stdlib
`concurrent.interpreters`, PEP 734).
```

`try_set_start_method('subint')` gate on py3.13:
```
[expected] RuntimeError: Spawn method 'subint'
requires Python 3.14+ (stdlib
`concurrent.interpreters`, PEP 734).
```

Pytest `--spawn-backend=subint` on py3.13 (the new
UsageError wrapper kicking in):
```
ERROR: Spawn method 'subint' requires Python 3.14+
(stdlib `concurrent.interpreters`, PEP 734).
Current runtime: 3.13.11 (main, Dec  5 2025,
16:06:33) [GCC 15.2.0]
```

Collection probe: `404 tests collected in 0.18s`
(no import errors from the new module).

Spawn-relevant test subset (`tests/test_local.py
test_rpc.py test_spawning.py test_multi_program.py
tests/discovery/`):
```
69 passed, 1 skipped, 10 warnings in 61.38s
```

Full suite was **not** run on py3.13 for this commit
— the scaffolding is no-op on <3.14 and full-suite
validation under py3.14 is pending that venv being
set up by the user.

### Commit message

Also AI-drafted (via `/commit-msg`, with the prose
rewrapped through `/home/goodboy/.claude/skills/pr-msg/
scripts/rewrap.py --width 67`) — the 33-line message
on commit `5cd6df58` itself. Not reproduced here; see
`git log -1 5cd6df58`.

### Known follow-ups flagged to user

- **`uv.lock` deferred**: pin-bump regenerated cp314
  wheel entries in `uv.lock`, but the user chose to
  not stage `uv.lock` for this commit. Warned
  explicitly.
- **Phase B.2 needs py3.14 venv** — running the
  actual subint impl requires it; user said they'd
  set it up separately.
