---
model: claude-opus-4-7[1m]
service: claude
session: subints-spawner-phase-b1-impl
timestamp: 2026-04-17T12:44:37Z
git_ref: 5cd6df5
scope: code
substantive: true
raw_file: 20260417T124437Z_5cd6df5_prompt_io.raw.md
---

## Prompt

Continuing the Phase B work from the design sessions
logged in `20260417T034918Z_9703210_prompt_io.md` and
the Phase A impl in `20260417T035800Z_61a73ba_...`.

User direction at this step:
- "ok now let's continue with the subints part of the
  plan ya?" → kick off Phase B.
- After I proposed a 4-sub-phase breakdown (B.1
  scaffolding, B.2 min-viable spawn, B.3 lifecycle,
  B.4 test enablement), user: "ok can we continue
  with B" → approving the phasing and design
  defaults (thread-per-subint, UDS default,
  code-string bootstrap via `interp.exec()`).
- User switched the worktree to
  `subint_spawner_backend` (instead of opening a
  fresh worktree as I'd proposed): "i already
  switched branches in the wkt, you should work off
  `subint_spawner_backend` now".

Scope of this turn: **B.1 scaffolding only** —
wire the `'subint'` name through the spawn-method
registry + harness, add a feature-detected stub
module, bump pyproject. No actual spawn flow.

## Response summary

Produced the Phase B.1 scaffolding patch, landed as
commit `5cd6df58` (subject: `Add `'subint'` spawn
backend scaffold (#379)`). Four files changed,
+124 / -2 lines.

Key pieces (all generated by claude, reviewed by
human before commit):
- `tractor/spawn/_subint.py` — **new**; feature-
  detects `concurrent.interpreters`; `subint_proc()`
  stub raises `RuntimeError` on py<3.14 or
  `NotImplementedError` with issue-#379 URL on
  py≥3.14. Signature mirrors `trio_proc`/`mp_proc`
  so B.2 can drop the impl in without touching
  `_methods`.
- `tractor/spawn/_spawn.py` — adds `'subint'` to
  `SpawnMethodKey`, grows a `case 'subint'` arm in
  `try_set_start_method()` with feature-gate, re-
  imports `sys` for the gate-error msg, adds late
  `from ._subint import subint_proc` import and
  `_methods` entry.
- `tractor/_testing/pytest.py` — converts the
  gate-error into `pytest.UsageError` via a
  `try/except` around `try_set_start_method()` so
  `--spawn-backend=subint` on py<3.14 prints a
  clean banner instead of a traceback.
- `pyproject.toml` — pin `requires-python` `<3.14`
  → `<3.15`, add `3.14` trove classifier.

## Files changed

See `git diff 5cd6df5~1..5cd6df5 --stat`:

```
 pyproject.toml             |   3 +-
 tractor/_testing/pytest.py |   8 +++-
 tractor/spawn/_spawn.py    |  15 ++++++
 tractor/spawn/_subint.py   | 100 +++++++++++++++++++++++++
 4 files changed, 124 insertions(+), 2 deletions(-)
```

Validation on py3.13:
- registry/gate probe — OK; `_has_subints = False`,
  `subint_proc()` raises `RuntimeError` as expected.
- `try_set_start_method('subint')` — raises cleanly.
- `pytest --spawn-backend=subint` — exits with
  `pytest.UsageError` banner.
- Spawn-relevant test subset — 69 passed, 1 skipped.
- Full suite on py3.13 deferred (scaffolding is
  no-op on <3.14).
- Full-suite on py3.14 pending user setting up the
  venv.

## Human edits

None — committed as generated by claude. `uv.lock`
was intentionally left unstaged by the user (pin-
bump regenerated cp314 wheel entries but they were
deferred to a follow-up).
