Browse Source

G-076: adopt upstream dead-console fix - repl_handler delivered-event path; fixed_in gate set to 9.0.5

punk::repl (pending 0.5.2): repl_handler's full 'chan configure' probe is now
guarded - on runtimes carrying the upstream f10d91c2d3 fix a dead console is
DELIVERED as a readable event and the probe errors ('couldn't read console
mode: broken pipe'); previously this backgrounded and left the repl idle with
its reader inactive. Terminal input loss now routes through new
repl::console_input_lost - the same teardown console_watchdog uses (helper
shared by both paths; watchdog probe and message unchanged).

punk::lib (pending 0.5.0): check::tclbug_console_deadspin_fixed_in = 9.0.5
after the G-039 kill procedure passed on a zig-built core-9-0-branch runtime
with the watchdog disarmed (clean script-visible eof exit 0.2s after conhost
kill). One edit flips both consumers: 'help tcl' warning and watchdog arming.
Regression-verified on affected 9.0.3: bug=1, watchdog armed, rescue at 1.9s
via the shared teardown. Suites: console+repl+lib families 115/115.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 2 weeks ago
parent
commit
3ed033dae4
  1. 2
      src/modules/punk/AGENTS.md
  2. 13
      src/modules/punk/lib-999999.0a1.0.tm
  3. 1
      src/modules/punk/lib-buildversion.txt
  4. 43
      src/modules/punk/repl-999999.0a1.0.tm
  5. 1
      src/modules/punk/repl-buildversion.txt

2
src/modules/punk/AGENTS.md

@ -29,7 +29,7 @@ Source of truth for all modules under the `punk::*` namespace. This is the prima
- New modules under `punk::*` should be created as `<subpath>/<modulename>-999999.0a1.0.tm` following the namespace-to-path convention. - New modules under `punk::*` should be created as `<subpath>/<modulename>-999999.0a1.0.tm` following the namespace-to-path convention.
- punk::repl supports launch-time console selection (G-001): `repl::init -console <spec>` (any `punk::console::console_spec_resolve` spec form) selects the console the repl reads/writes; `repl::start`'s input channel argument is optional and defaults to the selected console's input. Repl output flows through per-repl channel state (`repl::conin/conout/conerr` - rputs maps stdout/stderr per-repl, conerr==conout for a foreign console pending G-011), the code interp's stdout/stderr are diverted via shellfilter `var` junction stacks and emitted to the console after each run (repltype punk/0 only so far), and eof/size/capability questions go through `repl::console_at_eof`/`repl::console_get_size` which dispatch to the selected `::opunk::Console` object's (possibly overridden) methods. Process-console behaviours (tcl_interactive prompt gating, stdin reopen on eof, raw-mode re-enable) apply only when no foreign console is selected. Tests: `src/tests/modules/punk/repl/testsuites/repl/consolebackends.test` (child-process drivers - a repl cannot run inside the shared testinterp; see the suite header). - punk::repl supports launch-time console selection (G-001): `repl::init -console <spec>` (any `punk::console::console_spec_resolve` spec form) selects the console the repl reads/writes; `repl::start`'s input channel argument is optional and defaults to the selected console's input. Repl output flows through per-repl channel state (`repl::conin/conout/conerr` - rputs maps stdout/stderr per-repl, conerr==conout for a foreign console pending G-011), the code interp's stdout/stderr are diverted via shellfilter `var` junction stacks and emitted to the console after each run (repltype punk/0 only so far), and eof/size/capability questions go through `repl::console_at_eof`/`repl::console_get_size` which dispatch to the selected `::opunk::Console` object's (possibly overridden) methods. Process-console behaviours (tcl_interactive prompt gating, stdin reopen on eof, raw-mode re-enable) apply only when no foreign console is selected. Tests: `src/tests/modules/punk/repl/testsuites/repl/consolebackends.test` (child-process drivers - a repl cannot run inside the shared testinterp; see the suite header).
- punk::repl has a dead-console watchdog (G-039): `repl::start` arms `repl::console_watchdog` (default 5s, read-only `chan configure -inputmode` probe) only for a tcl9 console input channel (-inputmode present) serving the process-default console on windows - the Tcl 9 console driver never delivers a dead console (killed conhost/terminal) to the script as a fileevent and its reader thread busy-loops on the persistent error, so without the watchdog an orphaned shell spins CPU forever. On probe failure the watchdog closes the input channel (stopping the driver's reader thread) and finishes the repl via the normal eof path. Piped, foreign-console and tcl 8.6 inputs never arm it. Root-cause and verification detail: `goals/archive/G-039-orphan-console-spin.md` (achieved 2026-07-12); upstream ticket FILED 2026-07-12: https://core.tcl-lang.org/tcl/tktview/f10d91c2d3 (full text with repro scripts in `TEMP_REFERENCE/tcl9-dead-console-spin-TICKET-DRAFT.md` - scripts elided from the web submission). The watchdog is version-conditional (G-076): arming additionally requires `punk::lib::check::has_tclbug_console_deadspin` to report the runtime affected - the same check `help tcl` surfaces - gated by `check::tclbug_console_deadspin_fixed_in` (empty until a released Tcl containing the verified upstream fix passes the G-039 kill-procedure re-verification; see `goals/G-076-tcl9-deadconsole-fix-adoption.md`). - punk::repl has a dead-console watchdog (G-039): `repl::start` arms `repl::console_watchdog` (default 5s, read-only `chan configure -inputmode` probe) only for a tcl9 console input channel (-inputmode present) serving the process-default console on windows - the Tcl 9 console driver never delivers a dead console (killed conhost/terminal) to the script as a fileevent and its reader thread busy-loops on the persistent error, so without the watchdog an orphaned shell spins CPU forever. On probe failure the watchdog closes the input channel (stopping the driver's reader thread) and finishes the repl via the normal eof path. Piped, foreign-console and tcl 8.6 inputs never arm it. Root-cause and verification detail: `goals/archive/G-039-orphan-console-spin.md` (achieved 2026-07-12); upstream ticket FILED 2026-07-12: https://core.tcl-lang.org/tcl/tktview/f10d91c2d3 (full text with repro scripts in `TEMP_REFERENCE/tcl9-dead-console-spin-TICKET-DRAFT.md` - scripts elided from the web submission). The watchdog is version-conditional (G-076): arming additionally requires `punk::lib::check::has_tclbug_console_deadspin` to report the runtime affected - the same check `help tcl` surfaces - gated by `check::tclbug_console_deadspin_fixed_in`, set to `9.0.5` 2026-07-20 after the upstream fix (ticket closed 2026-07-14, merged to core-9-0-branch) passed the G-039 kill-procedure re-verification on a zig-built core-9-0-branch runtime with the watchdog disarmed. Runtimes at or past 9.0.5 do not arm the watchdog: the fixed driver DELIVERS the dead console as a readable fileevent, and `repl_handler` (punk::repl 0.5.2) treats the resulting `chan configure` probe error as terminal input loss via `repl::console_input_lost` - the same teardown the watchdog uses (close channel, finish via the eof done-path, no reopen attempt). Earlier Tcl 9 windows runtimes keep the watchdog (the defect never delivers the event there).
- punk::console uses the documented `-console` convention throughout: a `-console` value may be a 2-element {in out} channel list, an anchored `opunk::console` instance name, or an `::opunk::Console` object value (resolved via `punk::console::console_spec_resolve`). Query functions use the hybrid pattern (legacy trailing positional spec also accepted, parsed by `punk::console::internal::hybrid_console_spec`) - new query procs must follow it, with tests (see `src/tests/modules/punk/console/testsuites/console/queryprocs.test`). PUNKARGS definitions include the `-console` option via the shared fragments `::punk::console::argdoc::console_opts` (query/set functions) or `::punk::console::argdoc::console_emit_opts` (emit functions) rather than duplicating the option text; never re-add a `-minsize 2` constraint to `-console` (it rejects instance-name specs). The internal `get_size_using_*` size mechanisms deliberately remain canonical-pair positional (always fed by `get_size`). - punk::console uses the documented `-console` convention throughout: a `-console` value may be a 2-element {in out} channel list, an anchored `opunk::console` instance name, or an `::opunk::Console` object value (resolved via `punk::console::console_spec_resolve`). Query functions use the hybrid pattern (legacy trailing positional spec also accepted, parsed by `punk::console::internal::hybrid_console_spec`) - new query procs must follow it, with tests (see `src/tests/modules/punk/console/testsuites/console/queryprocs.test`). PUNKARGS definitions include the `-console` option via the shared fragments `::punk::console::argdoc::console_opts` (query/set functions) or `::punk::console::argdoc::console_emit_opts` (emit functions) rather than duplicating the option text; never re-add a `-minsize 2` constraint to `-console` (it rejects instance-name specs). The internal `get_size_using_*` size mechanisms deliberately remain canonical-pair positional (always fed by `get_size`).
- punk::console emit-side functions (the `punk::console::ansi::*` emit wrappers, mouse/paste toggles, `vt52`, `set_tabstop_width`, `titleset`, top-level `move`, and the width-test probes) accept an optional trailing `-console <consolespec>` pair, parsed manually for performance by `punk::console::internal::opt_console_out`/`opt_console_channels` (`_var` variants for procs whose args-tail also carries row/col/data triples). Each carries a documentation-only PUNKARGS definition that includes the shared `::punk::console::argdoc::console_emit_opts` fragment via `punk::args::resolved_def`; keep manual parsing and PUNKARGS synchronized. New emit procs must follow this pattern. Tests live in `src/tests/modules/punk/console/testsuites/console/emitconsole.test`. - punk::console emit-side functions (the `punk::console::ansi::*` emit wrappers, mouse/paste toggles, `vt52`, `set_tabstop_width`, `titleset`, top-level `move`, and the width-test probes) accept an optional trailing `-console <consolespec>` pair, parsed manually for performance by `punk::console::internal::opt_console_out`/`opt_console_channels` (`_var` variants for procs whose args-tail also carries row/col/data triples). Each carries a documentation-only PUNKARGS definition that includes the shared `::punk::console::argdoc::console_emit_opts` fragment via `punk::args::resolved_def`; keep manual parsing and PUNKARGS synchronized. New emit procs must follow this pattern. Tests live in `src/tests/modules/punk/console/testsuites/console/emitconsole.test`.
- punk::console terminal-property facts (is_vt52, tabwidth, cell_size, last_da1_result, grapheme_cluster_support, check::has_bug_*) are per-console: read/write them via `punk::console::console_fact_get`/`console_fact_set`, keyed by canonical {in out} channel pair. The store is tsv-backed (G-007) so all threads read the same values: the process-default console `{stdin stdout}` keeps the legacy namespace variables (`::punk::console::is_vt52`, `tabwidth`, ...) as its authoritative local storage with write traces mirroring into tsv `punk_console_facts` (so existing external readers and direct writers keep working); non-default consoles store facts only in tsv with an owner-qualified key. Do not bypass the helpers for non-default consoles; use `console_fact_clear` (not direct store manipulation) to reset facts in tests. `ansi_wanted`/`colour_disabled` (string-generation gates), `ansi_available` and raw-mode state are deliberately process-global (rationale documented at the fact store in the module). Tests live in `src/tests/modules/punk/console/testsuites/console/consolefacts.test`. - punk::console terminal-property facts (is_vt52, tabwidth, cell_size, last_da1_result, grapheme_cluster_support, check::has_bug_*) are per-console: read/write them via `punk::console::console_fact_get`/`console_fact_set`, keyed by canonical {in out} channel pair. The store is tsv-backed (G-007) so all threads read the same values: the process-default console `{stdin stdout}` keeps the legacy namespace variables (`::punk::console::is_vt52`, `tabwidth`, ...) as its authoritative local storage with write traces mirroring into tsv `punk_console_facts` (so existing external readers and direct writers keep working); non-default consoles store facts only in tsv with an owner-qualified key. Do not bypass the helpers for non-default consoles; use `console_fact_clear` (not direct store manipulation) to reset facts in tests. `ansi_wanted`/`colour_disabled` (string-generation gates), `ansi_available` and raw-mode state are deliberately process-global (rationale documented at the fact store in the module). Tests live in `src/tests/modules/punk/console/testsuites/console/consolefacts.test`.

13
src/modules/punk/lib-999999.0a1.0.tm

@ -252,11 +252,14 @@ tcl::namespace::eval punk::lib::check {
#G-076: version gate for the tcl9 dead-console defect (upstream ticket f10d91c2d3, root-caused #G-076: version gate for the tcl9 dead-console defect (upstream ticket f10d91c2d3, root-caused
#in G-039). Shared by the 'help tcl' warning and the repl dead-console watchdog arming (both #in G-039). Shared by the 'help tcl' warning and the repl dead-console watchdog arming (both
#consult has_tclbug_console_deadspin). Empty = no released Tcl is known to contain the upstream #consult has_tclbug_console_deadspin). Empty would mean no Tcl is known to contain the upstream
#fix, so every Tcl 9 windows runtime classifies as affected. Set this only after the G-039 kill #fix (every Tcl 9 windows runtime classifies as affected). Set to 9.0.5 2026-07-20: the upstream
#procedure, re-run on the fixed released runtime with the watchdog disabled, shows a clean #fix (ticket closed 2026-07-14; merged to core-9-0-branch, whose head reports 9.0.5) passed the
#script-visible eof exit (see goals/G-076-tcl9-deadconsole-fix-adoption.md). #G-039 kill procedure on a zig-built core-9-0-branch runtime with the watchdog disarmed - the
variable tclbug_console_deadspin_fixed_in "" #dead console arrived as a readable fileevent and the repl exited via the normal eof path
#(requires the punk::repl 0.5.2 repl_handler guard; an official release is not required per the
#amended acceptance - see goals/G-076-tcl9-deadconsole-fix-adoption.md 2026-07-20 entries).
variable tclbug_console_deadspin_fixed_in "9.0.5"
#pure classifier, separated for testability - facts in, verdict out #pure classifier, separated for testability - facts in, verdict out
proc tclbug_console_deadspin_applies {platform tclversion fixed_in} { proc tclbug_console_deadspin_applies {platform tclversion fixed_in} {

1
src/modules/punk/lib-buildversion.txt

@ -1,6 +1,7 @@
0.5.0 0.5.0
#First line must be a semantic version number #First line must be a semantic version number
#all other lines are ignored. #all other lines are ignored.
#0.5.0 - G-076: check::tclbug_console_deadspin_fixed_in set to 9.0.5 - the upstream f10d91c2d3 fix (ticket closed 2026-07-14, merged to core-9-0-branch whose head reports 9.0.5) passed the G-039 kill-procedure re-verification 2026-07-20 on a zig-built core-9-0-branch runtime with the watchdog disarmed (dead console delivered as a readable fileevent; repl exited via the eof path - needs punk::repl 0.5.2's repl_handler guard). Runtimes at or past 9.0.5 now neither warn via 'help tcl' nor arm the repl watchdog; earlier Tcl 9 windows runtimes keep both. Official release not required per the amended G-076 acceptance (self-built from upstream sources qualifies).
#0.5.0 - new check pair punk::lib::check::has_tclbug_nestedswitch_tracelines + tclbug_nestedswitch_tracelines_signature (pure facts-in/verdict-out classifier, G-076 console_deadspin style): live behavioural probe of upstream tcl tktview 5d5b1052280c976ea3d4 (execution-trace line mis-attribution for nested single-block switch arm bodies whose split-list index lands on a literal word of the switch command; punkshell-author-reported; punk-free repro scriptlib/developer/tcl_switch_traceline_repro.tcl, identical 8.6.17/8.7a6/9.0.3). The probe defines a dynamic-body proc, enterstep-traces inner arm 1 (affected index 1 -> reports 3) vs the default arm (index 5, beyond the 4-word command -> reports 2) and matches the characterized wrong/right signature - so detection flips automatically on a fixed Tcl (no version gate; followup steps for that day documented in the proc: re-verify with the repro script, flip the ns/cmdtrace.test GAP pins + canary, update the cmdtrace argdoc caveat, note fixed-in version). Surfaced via 'help tcl' warnings (level medium) alongside the other has_tclbug_* checks; probe is self-cleaning (temp proc/var removed in finally). #0.5.0 - new check pair punk::lib::check::has_tclbug_nestedswitch_tracelines + tclbug_nestedswitch_tracelines_signature (pure facts-in/verdict-out classifier, G-076 console_deadspin style): live behavioural probe of upstream tcl tktview 5d5b1052280c976ea3d4 (execution-trace line mis-attribution for nested single-block switch arm bodies whose split-list index lands on a literal word of the switch command; punkshell-author-reported; punk-free repro scriptlib/developer/tcl_switch_traceline_repro.tcl, identical 8.6.17/8.7a6/9.0.3). The probe defines a dynamic-body proc, enterstep-traces inner arm 1 (affected index 1 -> reports 3) vs the default arm (index 5, beyond the 4-word command -> reports 2) and matches the characterized wrong/right signature - so detection flips automatically on a fixed Tcl (no version gate; followup steps for that day documented in the proc: re-verify with the repro script, flip the ns/cmdtrace.test GAP pins + canary, update the cmdtrace argdoc caveat, note fixed-in version). Surfaced via 'help tcl' warnings (level medium) alongside the other has_tclbug_* checks; probe is self-cleaning (temp proc/var removed in finally).
#0.4.3 - G-076: buginfo dicts gain an optional mitigated/mitigation axis (mitigated boolean + mitigation text) orthogonal to level - a check whose defect is covered by a shipped punkshell mitigation reports it so 'help tcl' can render the warning subdued while keeping the severity classification. has_tclbug_console_deadspin populates it: mitigated when punk::repl >= 0.5.0 (console liveness watchdog) is available to the runtime (udp-check-style version discovery without loading), with the watchdog scope described in the mitigation text (non-repl console reads remain exposed). #0.4.3 - G-076: buginfo dicts gain an optional mitigated/mitigation axis (mitigated boolean + mitigation text) orthogonal to level - a check whose defect is covered by a shipped punkshell mitigation reports it so 'help tcl' can render the warning subdued while keeping the severity classification. has_tclbug_console_deadspin populates it: mitigated when punk::repl >= 0.5.0 (console liveness watchdog) is available to the runtime (udp-check-style version discovery without loading), with the watchdog scope described in the mitigation text (non-repl console reads remain exposed).
#0.4.2 - G-076: new punk::lib::check::has_tclbug_console_deadspin + tclbug_console_deadspin_applies classifier - version-based detection of the tcl9 windows dead-console defect (f10d91c2d3, root-caused in G-039: dead console never delivered as a fileevent + core reader thread busy-loop). Gate variable check::tclbug_console_deadspin_fixed_in (empty = no fixed release known - all Tcl 9 windows affected); shared by the 'help tcl' warning and repl::start's watchdog arming. #0.4.2 - G-076: new punk::lib::check::has_tclbug_console_deadspin + tclbug_console_deadspin_applies classifier - version-based detection of the tcl9 windows dead-console defect (f10d91c2d3, root-caused in G-039: dead console never delivered as a fileevent + core reader thread busy-loop). Gate variable check::tclbug_console_deadspin_fixed_in (empty = no fixed release known - all Tcl 9 windows affected); shared by the 'help tcl' warning and repl::start's watchdog arming.

43
src/modules/punk/repl-999999.0a1.0.tm

@ -1012,20 +1012,32 @@ proc repl::console_watchdog {inputchan} {
} }
if {[catch {chan configure $inputchan -inputmode}]} { if {[catch {chan configure $inputchan -inputmode}]} {
#GetConsoleMode failed - the hosting console is gone. #GetConsoleMode failed - the hosting console is gone.
#Close the channel (stops the tclWinConsole.c reader thread's error busy-loop) console_input_lost $inputchan "console_watchdog: console unavailable for '$inputchan' - closing input and finishing repl (eof)"
#and finish the repl via the normal eof path. Do not attempt a console reopen:
#with the console dead, CONIN$ cannot be opened either (app-punkshell's eof
#handling makes the same discovery and exits cleanly).
array unset console_watchdog_afterids $inputchan
catch {chan event $inputchan readable {}}
catch {chan close $inputchan}
catch {puts stderr "|repl> console_watchdog: console unavailable for '$inputchan' - closing input and finishing repl (eof)"}
set ::repl::done [list eof $inputchan]
return return
} }
set console_watchdog_afterids($inputchan) [after $console_watchdog_ms [list [namespace current]::console_watchdog $inputchan]] set console_watchdog_afterids($inputchan) [after $console_watchdog_ms [list [namespace current]::console_watchdog $inputchan]]
} }
proc repl::console_input_lost {inputchan msg} {
#Shared terminal path for a dead/unusable console input channel (G-039/G-076),
#used by console_watchdog (polling rescue on defect-carrying tcl9 runtimes) and by
#repl_handler (runtimes carrying the upstream f10d91c2d3 fix deliver the dead
#console as a readable event instead).
#Close the channel (stops the tclWinConsole.c reader thread's error busy-loop)
#and finish the repl via the normal eof done-path. Do not attempt a console reopen:
#with the console dead, CONIN$ cannot be opened either (app-punkshell's eof
#handling makes the same discovery and exits cleanly).
variable console_watchdog_afterids
if {[info exists console_watchdog_afterids($inputchan)]} {
catch {after cancel $console_watchdog_afterids($inputchan)}
array unset console_watchdog_afterids $inputchan
}
catch {chan event $inputchan readable {}}
catch {chan close $inputchan}
catch {puts stderr "|repl> $msg"}
set ::repl::done [list eof $inputchan]
}
namespace eval repl::argdoc { namespace eval repl::argdoc {
lappend PUNKARGS [list { lappend PUNKARGS [list {
@id -id ::repl::console_get_size @id -id ::repl::console_get_size
@ -1852,7 +1864,18 @@ proc repl::repl_handler {inputchan readmore prompt_config} {
#According to DKF - -buffering option doesn't affect input channels #According to DKF - -buffering option doesn't affect input channels
set rawmode 0 set rawmode 0
set waiting_needs_reader 0 ;#set when the 8.6-console waiting-chunks path skips its read on a drained channel - the readable handler must be armed (not the after-idle reinvoke) or the pending partial line could never complete set waiting_needs_reader 0 ;#set when the 8.6-console waiting-chunks path skips its read on a drained channel - the readable handler must be armed (not the after-idle reinvoke) or the pending partial line could never complete
set original_input_conf [chan configure $inputchan] ;#whether repl is in line or raw mode - we restore the inputchan (stdin) state if {[catch {chan configure $inputchan} original_input_conf]} {
#A runtime carrying the upstream tcl9 dead-console fix (f10d91c2d3) DELIVERS a
#dead console as a readable event, and this full option probe then errors
#(e.g 'couldn't read console mode: broken pipe'). Pre-fix runtimes never notify
#script level of a dead console (the console_watchdog poll covers those), so
#reaching here with a dead console requires the fixed driver. Terminal input
#loss - same teardown as the watchdog, no reopen attempt.
set in_repl_handler [list]
console_input_lost $inputchan "repl_handler: input channel unusable ($original_input_conf) - closing input and finishing repl (eof)"
return
}
#original_input_conf: whether repl is in line or raw mode - we restore the inputchan (stdin) state
if {[dict exists $original_input_conf -inputmode]} { if {[dict exists $original_input_conf -inputmode]} {
#review - when terminal is mintty and we switch to raw mode, the change isn't relected in chan configures '-inputmode' why? #review - when terminal is mintty and we switch to raw mode, the change isn't relected in chan configures '-inputmode' why?

1
src/modules/punk/repl-buildversion.txt

@ -1,6 +1,7 @@
0.5.2 0.5.2
#First line must be a semantic version number #First line must be a semantic version number
#all other lines are ignored. #all other lines are ignored.
#0.5.2 - G-076: repl_handler now handles a dead console DELIVERED as a readable event (runtimes carrying the upstream f10d91c2d3 fix - first such 9.0-line version 9.0.5): the previously unguarded full 'chan configure' probe at handler entry errored ('couldn't read console mode: broken pipe'), backgrounding the error and leaving the repl idle with its reader inactive. The probe is now guarded, and terminal input loss routes through new repl::console_input_lost - the same teardown console_watchdog uses (cancel any watchdog schedule, deregister reader, close channel to stop the core reader thread, finish via the eof done-path; no reopen attempt). console_watchdog now shares this helper (probe unchanged, message unchanged). Verified with the G-039 kill procedure on a zig-built core-9-0-branch (9.0.5) runtime with the watchdog disarmed via the shipping gate: clean exit 0.2s after conhost kill through app-punkshell's no-console eof handling; pre-fix runtimes are unaffected (the defect never delivers the event - the watchdog remains their rescue path).
#0.5.2 - fixed the codethread seeding template in repl::start: it namespace-eval'd the full ::punk::nav::ns::ns_current VARIABLE name (creating a stray namespace of that name in every code interp - visible as a phantom 'ns_current' child when browsing the nav namespace with n/) instead of just ensuring the parent ::punk::nav::ns exists before setting the variable. Seeding semantics unchanged (the subshell namespace carry-over: a new codethread's code interp starts in the launching context's ns_current when it exists, else ::). Guarded by the new punk/repl testsuite repl/nscurrent.test (real codethread via repl::init driven with synchronous runscript sends: inscope evaluation of ns_current, retention across submissions, n/-navigation retained, auto-create-with-notice for a missing current namespace, stray-namespace absence, and a source-text guard on the template pending an end-to-end piped subshell test). #0.5.2 - fixed the codethread seeding template in repl::start: it namespace-eval'd the full ::punk::nav::ns::ns_current VARIABLE name (creating a stray namespace of that name in every code interp - visible as a phantom 'ns_current' child when browsing the nav namespace with n/) instead of just ensuring the parent ::punk::nav::ns exists before setting the variable. Seeding semantics unchanged (the subshell namespace carry-over: a new codethread's code interp starts in the launching context's ns_current when it exists, else ::). Guarded by the new punk/repl testsuite repl/nscurrent.test (real codethread via repl::init driven with synchronous runscript sends: inscope evaluation of ns_current, retention across submissions, n/-navigation retained, auto-create-with-notice for a missing current namespace, stray-namespace absence, and a source-text guard on the template pending an end-to-end piped subshell test).
#0.5.1 - G-076: repl::start's dead-console watchdog arming now also requires punk::lib::check::has_tclbug_console_deadspin to report the runtime affected (shared version gate with the 'help tcl' warning; requires punk::lib 0.4.2+). Behaviour today is unchanged (gate variable check::tclbug_console_deadspin_fixed_in is empty = every Tcl 9 windows runtime affected); once a released Tcl containing the verified upstream fix for f10d91c2d3 is recorded there, such runtimes stop arming the watchdog. #0.5.1 - G-076: repl::start's dead-console watchdog arming now also requires punk::lib::check::has_tclbug_console_deadspin to report the runtime affected (shared version gate with the 'help tcl' warning; requires punk::lib 0.4.2+). Behaviour today is unchanged (gate variable check::tclbug_console_deadspin_fixed_in is empty = every Tcl 9 windows runtime affected); once a released Tcl containing the verified upstream fix for f10d91c2d3 is recorded there, such runtimes stop arming the watchdog.
#0.5.0 - G-039: new repl::console_watchdog - a self-rescheduling liveness poll (default 5s, repl::console_watchdog_ms) armed by repl::start for a tcl9 console input channel (-inputmode present) serving the process-default console on windows. The Tcl 9 windows console driver never delivers a dead console (killed conhost/terminal) to the script level as a fileevent (tclWinConsole.c ConsoleEventProc only notifies on buffered data) and its reader thread busy-loops on the persistent channel error, so an orphaned shell previously spun ~2 cores indefinitely. On a failed probe (chan configure -inputmode = live GetConsoleMode) the watchdog closes the input channel (stopping the driver reader thread) and finishes the repl via the normal eof done-path; app-punkshell's eof handling then finds no console reopenable and exits cleanly. repl::start's post-vwait reader-deregistration now tolerates an inchan closed by the watchdog. Piped/foreign-console/tcl8.6 inputs are unaffected (watchdog not armed). #0.5.0 - G-039: new repl::console_watchdog - a self-rescheduling liveness poll (default 5s, repl::console_watchdog_ms) armed by repl::start for a tcl9 console input channel (-inputmode present) serving the process-default console on windows. The Tcl 9 windows console driver never delivers a dead console (killed conhost/terminal) to the script level as a fileevent (tclWinConsole.c ConsoleEventProc only notifies on buffered data) and its reader thread busy-loops on the persistent channel error, so an orphaned shell previously spun ~2 cores indefinitely. On a failed probe (chan configure -inputmode = live GetConsoleMode) the watchdog closes the input channel (stopping the driver reader thread) and finishes the repl via the normal eof done-path; app-punkshell's eof handling then finds no console reopenable and exits cleanly. repl::start's post-vwait reader-deregistration now tolerates an inchan closed by the watchdog. Piped/foreign-console/tcl8.6 inputs are unaffected (watchdog not armed).

Loading…
Cancel
Save