PyCForge 1.3.48 — Bounded Python checks and responsive shutdown
Prepared 2026-10-20 from the verified 1.3.47 source archive.

RELEASE SCOPE

This release addresses audit F03/F04: Python Check bypassed the shared work
budget, and checker shutdown could wait for a process on the GUI thread.

Python Check now reserves a shared background-work slot before creating its
isolated QProcess. Explicit editor/conversion requests retain priority 0,
Python Check uses priority 1, and passive observers retain priority 2. A queued
scan has no child process. Budget-change notifications wake admission through
a queued Qt signal; the checker does not repeatedly poll for admission.

The dialog and recent-results dropdown distinguish queued and running scans.
Queue time is separate from execution time; the 60-second deadline starts on
admission. Scans retain the source captured when Scan was pressed. Subsequent
edits continue to invalidate results, including edits while a scan is queued.

Cancel removes queued work immediately. A running child is transferred to an
application-owned cleanup object. Termination is asynchronous, with a kill
fallback after 250 ms; the capacity slot remains reserved until Qt confirms
exit. Normal Qt quit is deferred while this cleanup finishes. No GUI-thread
waitForFinished remains in the checker. The outline service is also closed
without its previous 50 ms GUI-thread join; its existing worker owns cleanup.

The checker limits cumulative stdout to 2,000,000 bytes, including consumed
progress messages, and retains the existing 65,536-byte stderr limit. Failed
starts, invalid output, timeouts and abnormal exits all release capacity once.
No new process pool or runtime dependency was introduced.

All 144 converter files and all 10 Python-check analysis/ruleset files match
1.3.47 byte for byte. Save-integrity behavior from 1.3.47 is retained. The
baseline archive SHA256 is:
4498455ad7476d4ad17e70955485f42da8993909384a31aca213ca080bcee6ed

VALIDATION

Environment: Python 3.12.14, PySide6 6.12.0, Linux, QT_QPA_PLATFORM=offscreen.
Nineteen new scheduling/lifecycle cases cover admission, priorities, queued
cancellation, worker-thread wakeups, startup failure, abnormal exit, invalid
responses, cumulative output bounds, timeouts, dialog deletion, normal
last-window exit and the compact recent-results view.

The queued-admission probe observes one admission attempt across a 300 ms
interval with occupied capacity. A simulated 120-second queue age does not
consume the execution deadline. Slow real children ignore graceful termination:
cancel, timeout and shutdown handlers return within 200 ms in the tests, GUI
heartbeat timers keep firing through cleanup, and the slot remains occupied
until child exit. These are regression bounds, not general throughput claims.

The focused run passed 42 tests and 488 subtests, including existing Help and
startup contracts and two new documentation navigation checks. It overlaps the
broader regression run and should not be added to that run's totals.

Broad run: 118 test modules; 1,456 passed, 13 skipped and 3,519 subtests
passed. Two checks initially failed: a historical source assertion still
required the removed 50 ms wait, and a Run Python test inspected Save As before
the asynchronous save completed. The tests now require a zero GUI wait and
wait for save completion before asserting the control state. No functional
product change was needed to resolve either result.

Follow-up: both affected modules plus all new scheduling/navigation cases;
55 passed and 47 subtests passed, with no failures. Both initially failing
checks passed. The runs overlap and their counts must not be added. All selected
checks have passed; raw logs preserve the initial failures and their resolution.
An earlier interrupted invocation is retained separately and is not counted.

The 13 skips are eight unavailable-Clang cases and five historical validator
cases requiring a sealed predecessor archive not supplied beside this tree.

HTML HELP AND README

All 30 pages open in the installed Help renderer, and 51 topic searches resolve
to the intended pages. Offline links, fragments, unique identifiers and catalog
order are checked. Previous/Next footers now follow the complete reading order.
Detailed Python Check instructions have their own searchable page; the existing
workspace anchor remains a short entry point. The guide explains queueing,
captured source, cancellation, stale findings and actual limits.

All 81 documented Python examples pass native comparisons: 32 Typed and 49
Runtime examples. The 32 Typed examples also pass separate-module compilation.
Five Python API examples, four C callers, three supplied-module examples, three
export examples and three README Python examples pass their documented checks.
The documentation verifier now reads generated record field names from the ABI
manifest and checks the current version rather than an old 1.3.40 heading.

The new Help page was visually reviewed at 1220x850 and 900x680. Text wraps,
section links remain usable and navigation is visible. Review images stay out
of release archives. Existing screenshot assets and application icons remain.

README changes are limited to the 1.3.48 heading, 30-page count and correction of
an outdated record-binding restriction. Record locals/parameters already support
same-class reassignment through branches and loops. The README remains 227
lines: 3,415 words versus 3,409 before. Its existing structure and professional
scope are preserved; no development logs or roadmap were added.

Exactly four approved image links remain, in their original order: PyCForge
banner, workspace screenshot, Ting screenshot, and Crucible banner. Banner
widths remain 320 and 640; screenshot labels remain 1.3.39. The Crucible subtitle
and placement below the Conversion bug tracker are unchanged. The README
renderer verifies four images and zero authored navigation links. AGENTS.md and
PyCForge-README-Guidelines.txt remain in the source archive.

LIMITS AND NEXT WORK

The shared budget is an admission counter for participating operations, not a
whole-application CPU or memory quota. Existing worker-thread waits in other
services are unchanged. Forced process termination, OS shutdown and app.exit()
are outside the normal Qt-quit cleanup guarantee. This update does not claim
that every background-service lifecycle has been redesigned.

Native Windows/macOS interaction and display scaling were not exercised in this
Linux offscreen environment. Native acceptance should cover occupied-capacity
scans, cancel/re-scan, closing the last window during a running check, and Help
navigation. Incremental revision indexing and Help-cache work remain subsequent
audit items; they are not claimed fixed here.

Raw logs, test selection, documentation results, README diff and unchanged-file
hash inventories are in evidence/check_scheduling_1_3_48. The final handoff adds
checks on the exact wheel/source pair, installed validation, byte sizes and
SHA256 values. Final artifact hashes remain outside the source archive to avoid
a self-referential checksum. Only CC publishes PyCForge to PyPI.
