Skip to content

doctor: report the interpreter architecture and what -n auto will really ask for; name the one exemption to the ASCII fold (#367, #376) - #387

Merged
fdaviddpt merged 5 commits into
mainfrom
fix/376
Aug 20, 2026
Merged

doctor: report the interpreter architecture and what -n auto will really ask for; name the one exemption to the ASCII fold (#367, #376)#387
fdaviddpt merged 5 commits into
mainfrom
fix/376

Conversation

@fdaviddpt

@fdaviddpt fdaviddpt commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Two issues in scripts/doctor.py, one lane because they are the same file and because #376 is the rule #367's new lines have to obey.

#367 — the interpreter architecture and the worker count

Three new lines, all needing no config, printed above the check_tool probes because those spawn subprocesses and the first line is what explains what a subprocess costs here.

interpreter architecture — whether this python3 is running under binary translation. platform.machine() cannot answer it and neither can uname -m from a subprocess: an emulated process is shown the emulated architecture and so is everything it spawns, so the comparison is one number against itself. The probe is macOS's sysctl.proc_translated, read in-process through ctypes rather than by spawning sysctl, which would inherit the question. The sysctl's absence is read as Apple documents it — no translation layer on this system, i.e. native — so Intel Macs answer correctly rather than shrugging.

cpu topology and worker sizing — the logical core count with the performance/efficiency split where the platform exposes it, and what pytest -n auto would actually request, transcribing xdist's own order: PYTEST_XDIST_AUTO_NUM_WORKERS first (it is read before anything is counted, which is the cap you have to know is there), then psutil's physical count — -n auto passes logical=False, so on an SMT machine reporting os.cpu_count() would double the number — then sched_getaffinity, then os.cpu_count().

On this machine that reproduces the incident exactly: 11 logical core(s) -- 5 performance + 6 efficiency, and -n auto would request 11.

The three open questions in the issue, decided

  • Report PYTEST_XDIST_AUTO_NUM_WORKERS when set, or only the resulting count? Both. The count is what you came for; the variable is named as its source when it wins, and when it is set to something that is not a number the line says xdist warns and ignores it, so a reader does not think a cap is in effect that is not.
  • Does an agent count belong beside it? No, and the issue's own suspicion was right. No python process can see its sibling agents, and a line that guessed would be the defect this repo is named after. Left for filing as its own issue; the worker sizing line says instead that concurrent agents each size against the whole machine without seeing each other, which is the true half.
  • Platforms with no performance/efficiency split? The line degrades to a plain core count and says the split is absent, rather than omitting the clause — an omitted clause reads exactly like a machine whose split nobody looked for.

The third state, three times

No translation probe exists for Linux (qemu-user) or Windows-on-ARM, so both report not probed with the reason on the line, and the line never contains the word native in that state.

That state started life as a WARN, and CI settled it in one round: it made VERDICT: ok unreachable on every Linux and Windows leg, which broke test_verdict_says_ok_only_when_nothing_warned — a guard I did not touch and which is right. A permanent unclearable WARN on two of three platforms does not add a finding, it removes a signal: a verdict that always reads usable with gaps can no longer carry a real WARN, so every genuine gap there is masked by a permanent one. This repo's own defect class, pointed at the verdict line rather than at a check.

So the state is now two states. not-probed — no probe exists for this platform at all — is OK, with the gap named on the line; that is the shape agent_dispatch already uses one screen up in the same file for a sub-question no script can read. unknown — a probe that exists here, ran, and did not answer — keeps its WARN, because it has a cause worth chasing. The guard is not relaxed by a byte: it still asserts VERDICT: ok, so a second unrelated WARN still fails it, which a relaxation to one warning is fine would not have done.

An earlier revision of this branch said in README.md, commands/doctor.md and the fragment that if the standing WARN proved to be noise, the thing to change was the probe and not the state. That is retracted in all three. It was wrong twice: it framed the choice as WARN-or-silence when a third shape already existed in the same file, and it cannot be carried out anyway — Windows has a real probe available (IsWow64Process2, filed rather than added here, since it is a ctypes call against an API this lane cannot run), but every Linux qemu-user self-detection worth having is a heuristic that fails toward clean, which is a confident wrong answer and strictly worse than a named gap.

Self-review found the same seam twice more, one level down, and both are fixed here: hw.optional.arm64 and hw.nperflevels each return nothing both when the answer is genuinely negative and when the call failed. The first printed host architecture x86_64 about a host nobody read — and interpolated that unread architecture into A native <host> python3 removes the tax, a remedy the reader is meant to act on, rendering literally as A native None python3. The second printed this platform reports no performance/efficiency core split for a probe that had failed, telling the reader the count sizes against uniform cores when nobody established that.

Note checked before writing a probe twice

The issue asks whether Digital-Process-Tools/claude-supertool#1857 landed first, so this could relay rather than reimplement. It has not: that issue is OPEN with no linked PRs at the time of writing. Implemented here.

#376 — the contract and the exemption

Settled toward amending the contract, not folding the remedy. report_with_remedy's own docstring scopes the exemption to remedy, built from PLUGIN_ROOT — this script's own resolved install location, not text the audited tree chose — and folding it puts a ?, a shell glob, inside a command the reader is meant to paste and run. That is #344, which the exemption exists to fix; routing the remedy back through the fold would reinstate a filed defect to satisfy a sentence, and the sentence is what did not move. The contract now names the one exempt fragment, says what it still gets (the newline and control-character collapse, plus _safe_print's encoding net), and says nothing else is exempt.

The guard was judged worth having rather than a one-line correction on one ground: it is a second measurement, not the same claim twice. tests/test_doctor_fold_contract_376.py reads the emitter set out of the AST and the exemption out of the prose, and a finding is the two disagreeing — a test asserting only the docstring says X would pass whenever the docstring and the code were wrong together, which is the shape of #376 itself. Three must-fire controls over synthetic source, so a scan that could see nothing fails there rather than passing.

Testing

TDD in order, red watched separately each time: the #376 guard red against the pre-#376 wording (the module contract never names report_with_remedy; ... never says any fragment is exempt ...), the #367 tests red at AttributeError: module 'doctor' has no attribute 'translation_state' (20 failed, 0 passed), and the two self-review findings red at A native None python3 removes the tax (11 failed).

Every rendering assertion runs against injected values, because this machine is native arm64 with no Rosetta — a test that measured the host would have tested the hardware. The three tests that can only run on Darwin skip loudly, naming what went untested.

Full suite: 2667 passed, 2 skipped, coverage 92.61% against an 85% floor.

The CI red was reproduced locally without a Linux runner, by patching platform.systemassert 'WARN' not in ['WARN', 'OK', 'OK'], assert 'unknown' == 'not-probed', assert ['WARN'] == ['OK'], 3 failed and 28 passed with both must-fire controls already green, which is what showed the WARN arm was being split rather than deleted.

Platform claims

Observed on macOS 15 / arm64 / CPython 3.13 only. Reasoned for the rest: ctypes is reached only behind platform.system() == 'Darwin'; os.sched_getaffinity is reached through getattr, so its absence on macOS and Windows is a None branch rather than an AttributeError; every new line is pure printable ASCII, so nothing here can raise UnicodeEncodeError on a cp1252 console; the whole file parses under the 3.9 grammar and introduces no f-string or walrus.

Closes #367
Closes #376

Verified by the maintainer

Two rounds of pushback, both taken, and the second one found more than I asked for.

Round one — the standing WARN. I sent this back rather than patching it, on the risk that relaxing
the guard to one warning is fine would pass against any future spurious warning. Checked:
tests/test_doctor_inprocess.py is not in the diff at all, so the guard was never touched — the
whole fix is product code. Measured against the branch: Linux -> not-probed, Darwin with
_sysctl stubbed mute -> unknown, real -> native. The WARN arm was split, not deleted.

Round two — one stale assertion, and three more behind it. I reported one failing line and asked
for a sweep rather than a fix to the line I could see. The sweep found test_unprobed_is_a_warn_…,
test_an_unprobed_line_never_claims_native and the ASCII-fold loop all pairing unknown with
system="Linux" — a composite the product can no longer produce, so all three were passing
vacuously. One visible failure, four stale assertions.

Red re-run: both new test files on origin/main, product code untouched — 32 failed, 6 passed.

The technique the author added is worth more than this diff: running the whole suite with
platform.system forced to Linux (2666 passed, 4 skipped) beside the native run (2667 passed, 3 skipped). Both of this branch's CI reds were reachable that way before either reached me, and neither
was reachable from a native run — which is CLAUDE.md's a green run on your own platform is the
weakest evidence available
, with a cheap way to stop paying for it.

fdaviddpt and others added 2 commits August 20, 2026 13:51
… name the one exemption to the ASCII fold (#367, #376)

#367 -- two facts about the machine that nothing printed and that were
decisive in an incident. `interpreter architecture` says whether this python3
is running under binary translation: `platform.machine()` cannot answer it,
because an emulated process is shown the emulated architecture and so is
anything it spawns, so the probe is macOS's `sysctl.proc_translated` read
in-process through ctypes, with the sysctl's absence read as Apple documents
it. Linux and Windows-on-ARM get the third state, `not probed`, rather than
being folded into `native`. `cpu topology` and `worker sizing` report the
performance/efficiency split where the platform exposes it and what
`pytest -n auto` would actually request, transcribing xdist's own order so the
PYTEST_XDIST_AUTO_NUM_WORKERS cap is stated rather than discovered.

#376 -- the module contract stated the printable-ASCII fold unconditionally
while `report_with_remedy` exempts its `remedy` argument. Settled by amending
the contract: folding the remedy would put a shell glob inside a command the
reader is meant to run, which is #344 reinstated. The contract now names the
one exemption and says nothing else is exempt, and a new guard holds the
paragraph and the set of `_emit` callers to each other.

Closes #367
Closes #376

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015HuQoqn4iLmW2ULpvhKnwj
…rd state as the translation flag (#367)

Both self-review findings, and both the same shape one level down from the
defect the check was written for. `hw.optional.arm64` returns nothing when the
machine is genuinely not arm64 AND when the call failed, so the first version
printed `host architecture x86_64` about a host nobody read -- and, worse, put
that unread architecture inside "A native <host> python3 removes the tax", a
remedy the reader is meant to act on. `hw.nperflevels` has the identical seam:
"one performance level" and "the probe failed" both rendered as "this platform
reports no performance/efficiency core split", which tells the reader the count
below sizes against uniform cores when nobody established that.

`translation_state` now returns host None when it was not established and the
renderer says so and names no architecture in the remedy; `cpu_topology`
returns a fourth slot, split/none/unknown, and `worker_sizing` WARNs on the
third. Both new states are asserted against injected values with a must-not-fire
control that would catch a fix collapsing everything into the cautious answer.

Also: README said "Two lines" for three (`interpreter architecture`, `cpu
topology`, `worker sizing`), disagreeing with commands/doctor.md added in the
same commit. And the standing WARN on Linux and Windows -- a consequence that
was decided and then written down nowhere -- is now recorded in README.md,
commands/doctor.md and the fragment, with the remedy named as writing a probe
for those platforms rather than softening the state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015HuQoqn4iLmW2ULpvhKnwj
fdaviddpt added a commit that referenced this pull request Aug 20, 2026
Owed by the session that cut the tag, and performed by it this time -- but after
PR #387 had already gone red on all three ubuntu legs for a staleness its diff
did not cause. That is #235 incurred rather than argued, and the section now
records it as an observation instead of a prediction.

Every figure re-measured at d4c12c1: 44 reach probes across 11 repositories, the
nine owned-file sha256 cells, three doctor verdicts, the jit hook fired with both
controls, the launcher diff, and the merged-PR count for the cycle.

New this round: gh resolves to an x86_64 build under Rosetta from the Intel
prefix and is two years old, which is #367s own class living one binary over,
unmeasured, in the tool the loop spawns most (#386).

Co-Authored-By: Max <noreply>
fdaviddpt and others added 2 commits August 20, 2026 14:37
… so VERDICT: ok stays reachable off Darwin (#367)

PR #387 went red on `tests/test_doctor_inprocess.py::test_verdict_says_ok_only
_when_nothing_warned`, on ubuntu/3.12 and by construction on every Linux and
Windows leg. It went green locally because this machine has a working
sysctl.proc_translated, so the WARN never fired here -- CLAUDE.md's "a green run
on your own platform is the weakest evidence available", landing on the
interpreter's own probe.

The guard is right and the state was wrong. A permanent unclearable WARN on two
of three platforms does not add a finding, it removes a signal: a verdict that
always reads `usable with gaps` can no longer carry a real WARN, so every
genuine gap on Linux and Windows is masked by a permanent one. That is this
repo's own defect class pointed at the verdict line instead of at a check, and
it is a bigger absence than the one the WARN reported.

So `translation_state` returns four states rather than three. `not-probed` --
no probe exists for this platform at all -- is reported at OK with the reason
named on the line, which is the shape `agent_dispatch` already uses in this same
file for a sub-question no script can read. `unknown` -- a probe that exists
here, ran and did not answer -- keeps its WARN, because it has a cause worth
chasing. Neither line says `native`, and that stays pinned.

The guard is not relaxed by a byte: it still asserts `VERDICT: ok`, so a second
unrelated WARN still fails it. Every new assertion is paired -- not-probed is OK
and a failing sysctl on Darwin is still WARN, at the line level and again at the
whole-check level, so a check that had stopped reporting anything could not pass
the first half.

Retracted in README.md, commands/doctor.md and the fragment, where I had written
that if the standing WARN proved to be noise the thing to change was the probe
rather than the state. That was wrong twice: it framed the choice as
WARN-or-silence when a third shape already existed one screen up in the same
file, and it cannot be carried out anyway -- Windows has a real probe available
(IsWow64Process2) but every Linux qemu-user self-detection worth having is a
heuristic that fails toward `clean`, which is a confident wrong answer and
strictly worse than a named gap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015HuQoqn4iLmW2ULpvhKnwj
…s, one of them red (#367)

`test_translation_state_answers_on_darwin` was one test doing two jobs, and its
non-Darwin arm was a cheap "does the function answer at all" check that named
`unknown` -- the state that no longer exists off Darwin. Red on every ubuntu leg
and invisible on macOS, where that arm never runs.

Not a string swap. It is two platforms making two different claims, so it is two
tests, and neither is the other's skip arm -- being a skip arm is what let the
stale assertion hide for a round.

* `test_translation_state_reaches_a_verdict_on_darwin`: the probe must reach
  native/translated and never shrug, ENOENT being itself the answer `native`.
* `test_translation_state_reports_not_probed_on_a_platform_with_no_probe`: the
  live dispatch on a platform with no probe. Distinct from the injected
  `test_off_darwin_...`, which pins the branch; this pins that the real
  `platform.system()` reaches it -- the branch being wrong and the branch being
  right but never reached are two failures. `not-probed` is the load-bearing
  half: `unknown` would report a fault where there is only a gap and cost a WARN
  no remedy clears, which is the whole of the previous round.

Swept the rest of the file rather than fixing the one leg named three more
fixtures pairing `unknown` with `system="Linux"` -- a composite the product can
no longer produce, so they passed no matter what the code did with the real
input. Re-pointed to reachable pairings, and the two obligations the split
doubled now cover both gap states: the never-says-`native` assertion and the
printable-ASCII fold, the latter over all six reachable renderings including the
two unread-host ones. `tests/test_doctor_fold_contract_376.py` reads no state
names at all, so it needed nothing.

Verified the way the last two rounds were not: the whole suite re-run with
`platform.system` forced to Linux -- 2666 passed, 4 skipped, no failures -- as
well as natively, 2667 passed, 3 skipped. Under Linux the new not-probed test
asserts and the Darwin pair skips; natively the reverse. Neither platform is
vacuous, and both skips name what went untested.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015HuQoqn4iLmW2ULpvhKnwj
@fdaviddpt
fdaviddpt merged commit c6b7acd into main Aug 20, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant