From 7309bb03fbad5584a1824ebe2c1e6aecc4e9d85d Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sat, 25 Jul 2026 02:34:17 +1000 Subject: [PATCH] G-120 proposed: 9.1-kit script-mode std-slot pin investigation (goal + index entry) Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai --- GOALS.md | 4 ++ goals/G-120-scriptmode-std-channel-pin.md | 59 +++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 goals/G-120-scriptmode-std-channel-pin.md diff --git a/GOALS.md b/GOALS.md index 229d7833..5e7f5c2b 100644 --- a/GOALS.md +++ b/GOALS.md @@ -409,3 +409,7 @@ Detail: goals/G-118-tclsh-subcommand-review.md ### G-119 [proposed] punk-runtime active-vs-default freshness verdict (ahead/behind/current) Scope: src/scriptapps/bin/punk-runtime.ps1 + punk-runtime.bash (+ rewrapped bin/punk-runtime.cmd); bin/AGENTS.md (runtime-manager contract); src/tests/modules/punk/mix/testsuites/scriptwrap/ (roundtrip pin; behavioural fixture surface settled in the work) Detail: goals/G-119-runtime-active-freshness.md + +### G-120 [proposed] 9.1-kit script-mode boot pins process std channels: find holder, restore std-slot recycling +Scope: src/modules/punk/console-999999.0a1.0.tm; src/modules/punk/repl-999999.0a1.0.tm; src/lib/app-punkscript/; src/vfs/_config/punk_main.tcl +Detail: goals/G-120-scriptmode-std-channel-pin.md diff --git a/goals/G-120-scriptmode-std-channel-pin.md b/goals/G-120-scriptmode-std-channel-pin.md new file mode 100644 index 00000000..023bfa5f --- /dev/null +++ b/goals/G-120-scriptmode-std-channel-pin.md @@ -0,0 +1,59 @@ +# G-120 9.1-kit script-mode boot pins process std channels: find holder, restore std-slot recycling + +Status: proposed +Scope: src/modules/punk/console-999999.0a1.0.tm; src/modules/punk/repl-999999.0a1.0.tm; src/lib/app-punkscript/; src/vfs/_config/punk_main.tcl +Goal: identify what in the 9.1-kit script-mode boot path retains a registration on the process std channels (keeping their std slots occupied and their OS handles alive across an explicit chan close), determine whether that retention is deliberate console-ownership machinery or a leak, and land the recorded disposition so that closing a std channel frees its slot - restoring Tcl's std-channel recycling - without breaking console abstraction behaviour. +Acceptance: the registration holder is named (module, proc, mechanism) with reproduction evidence; the disposition is recorded here (deliberate-and-documented, or fixed); a script-mode run of the recipe `chan close stderr; open NUL w` on the current 9.1 kit yields a channel auto-named stderr with working puts stderr, and the console + repl module suites (src/tests/modules/punk/console/, src/tests/modules/punk/repl/) pass. + +## Context + +Surfaced 2026-07-25 by the console-detach launch-mechanism spike (supporting G-101's +Tk-app launch story). Tcl installs the first channel created after an explicit +std-channel close into the vacated std slot (generic/tclIO.c Tcl_CreateChannel +std-slot install, verified in the TEMP_REFERENCE/tcl9 trunk) - this recycling works +on stock 9.1b0 (tclsfe-x64.exe), on punk902z (9.0.2) and on punk905 (9.0.5), but +NOT on punk91 (9.1b0 + current punk boot layer): there the std OS handle stays alive +after chan close (a registration is held somewhere in the boot path), the slot stays +occupied, and the new channel gets a fileN name, so puts stderr then fails with +"can not find channel named stderr". Consequence beyond cosmetics: in the 9.1 kit a +script cannot release/rebind the process std channels, which the detach launch +mechanism (G-101 Notes 2026-07-25) would otherwise use for in-place stdio repair. + +Ruled out by the spike: command interception (::open/::chan origins are core), the +repl interactive-EOF restart path (does not run in script mode), shellfilter stacks +(app-punkscript contract has none), the piperepl tclMain patch (punk91's tclsfe +runtime is unpatched per G-118 Notes). + +## Approach + +Instrument a script-mode boot to snapshot channel registrations, threads and open +channels at boot stages (or bisect module loads); the holder must be a +Tcl_RegisterChannel-equivalent (global or cross-interp) on a std channel - suspects +in load order: punk::console (ownership/registry anchoring, G-007 lineage), +punk::repl + codethread/shellthread setup, the app-punkscript boot itself. Confirm +by absence: strip the suspected stage and re-run the recipe. + +## Alternatives considered + +- Fold the investigation into G-101 - rejected (user decision 2026-07-25): G-101 is + the 8.6 container strategy; the pin is 9.1-kit boot-layer machinery in the console + lineage, and 8.6 kits already recycle. +- Accept as deliberate and design around it (relaunch-self only for 9.x) - fallback + disposition if the retention proves load-bearing for console ownership; the spike + showed relaunch-self already covers the launch requirement, so this goal's fix is + about restoring expected Tcl behaviour, not unblocking the launch path. + +## Notes + +- Related: G-118 (console-path machinery + piperepl residue territory; its Notes + record punk91's runtime as unpatched, ruling out the patch as the holder); G-011 + (stderr semantics - a recycled rebound stderr is a consumer of that goal's defined + routing); G-090 (shellfilter/shellthread stack lifecycle audit - adjacent + channel-lifetime territory); archived G-007 + (goals/archive/G-007-console-location-transparency.md - the console ownership + registry lineage the holder most likely belongs to). +- Overlap survey 2026-07-25 (goals_xref.tcl paths over the scope): surfaced + G-002/003/008/009/010/011/013/014/034/038/042/043/044 (punk/repl + punk/console + module-path sharing - repl-feature goals, no substantive pin relationship), G-077 + (app-punkscript), G-031/032/033/114/118 + others (punk_main.tcl boot-config + sharing); substantive relations recorded as Related lines above.