From c8f437b909e33368eb61e7f0cd5c8ef648c14cf7 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Wed, 8 Jul 2026 23:38:35 +1000 Subject: [PATCH] update vfs: _vfscommon modules punk 0.2.2, punk::lib 0.3.0 vfscommonupdate + project round (user-directed) so kit-stamped modules carry today's punk 0.2.2 (help doc folding) and punk::lib 0.3.0 (has_libbug_udp detection). Other modules were already current from the previous round. Rebuilt kits verified: plain punksys/punk902z launches report punk=0.2.2 lib=0.3.0 args=0.2.3 ns=0.1.1 udp=1.0.13. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- .../modules/{punk-0.2.0.tm => punk-0.2.2.tm} | 69 ++++++++++++++----- .../punk/{lib-0.2.1.tm => lib-0.3.0.tm} | 56 ++++++++++++++- 2 files changed, 106 insertions(+), 19 deletions(-) rename src/vfs/_vfscommon.vfs/modules/{punk-0.2.0.tm => punk-0.2.2.tm} (99%) rename src/vfs/_vfscommon.vfs/modules/punk/{lib-0.2.1.tm => lib-0.3.0.tm} (99%) diff --git a/src/vfs/_vfscommon.vfs/modules/punk-0.2.0.tm b/src/vfs/_vfscommon.vfs/modules/punk-0.2.2.tm similarity index 99% rename from src/vfs/_vfscommon.vfs/modules/punk-0.2.0.tm rename to src/vfs/_vfscommon.vfs/modules/punk-0.2.2.tm index a8086722..b34f1b43 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk-0.2.0.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk-0.2.2.tm @@ -8476,23 +8476,28 @@ namespace eval punk { dict set choicelabels $name [dict get $tinfo summary] } } + #keep help-text lines manually folded (~70 cols) - the usage tables don't yet + #wrap to terminal width, so line lengths here directly set the table width set basehelp {Help system for the punk shell. - With no arguments - an overview of some key shell commands is displayed. - When the first argument is a recognised topic - help for that topic is displayed. + With no arguments - an overview of some key shell + commands is displayed. + When the first argument is a recognised topic - help + for that topic is displayed. ('help topics' lists the available topics) - Anything else is treated as a command name - basic command info (type and - synopsis) is shown for a resolvable command, or the resolved path for an + Anything else is treated as a command name - basic + command info (type and synopsis) is shown for a + resolvable command, or the resolved path for an external executable.} - set topichelp {Help topic, or command words for basic command info. (topics must match exactly - no prefix matching)} + set topichelp "Help topic, or command words for basic command info.\n(topics must match exactly - no prefix matching)" set specs [list] lappend specs ::punk::help help "Punk shell help system." "" - lappend specs ::punk::help_chunks punk::help_chunks "Punk shell help system - content as {channel text} chunks." "\n\nhelp_chunks returns the help content as a list of {channel text} chunks rather than emitting it." + lappend specs ::punk::help_chunks punk::help_chunks "Punk shell help system - content as {channel text} chunks." "\n\nhelp_chunks returns the help content as a list of\n{channel text} chunks rather than emitting it." foreach {id name summary extra} $specs { set def "" append def "@id -id $id" \n append def "@cmd -name $name -summary \"$summary\" -help \"$basehelp$extra\"" \n append def "@leaders -min 0 -max -1" \n - append def "topic -optional 1 -multiple 1 -type string -choiceprefix 0 -choicerestricted 0 -choices {$choices} -choiceinfo {$choiceinfo} -choicelabels {$choicelabels} -help \"$topichelp\"" \n + append def "topic -optional 1 -multiple 1 -type string -choiceprefix 0 -choicerestricted 0 -choicecolumns 2 -choices {$choices} -choiceinfo {$choiceinfo} -choicelabels {$choicelabels} -help \"$topichelp\"" \n append def "@values -min 0 -max 0" if {[punk::args::id_exists $id]} { #quiet undefine - redefinition on registry change is expected, not noteworthy @@ -8548,7 +8553,12 @@ namespace eval punk { punk::args::define { @id -id ::punk::helptopic::topics - @cmd -name "help topics" -summary "List help topics." -help "Show the table of topics known to the help system, including registered aliases for each topic." + @cmd -name "help topics"\ + -summary\ + "List help topics."\ + -help\ + "Show the table of topics known to the help system, + including registered aliases for each topic." @values -min 0 -max 0 } proc topics {context args} { @@ -8570,7 +8580,15 @@ namespace eval punk { punk::args::define { @id -id ::punk::helptopic::tcl - @cmd -name "help tcl" -summary "Tcl version warnings." -help "Show the running Tcl patchlevel and build-info, with warnings for known Tcl bugs affecting this interpreter (as detected by the punk::lib::check::has_tclbug_* checks)." + @cmd -name "help tcl"\ + -summary\ + "Tcl version warnings."\ + -help\ + "Show the running Tcl patchlevel and build-info, with + warnings for known Tcl bugs affecting this interpreter + and known bugs in bundled library packages + (as detected by the punk::lib::check::has_tclbug_* + and has_libbug_* checks)." @values -min 0 -max 0 } proc tcl {context args} { @@ -8580,8 +8598,12 @@ namespace eval punk { catch { append text \n "Tcl build-info: [::tcl::build-info]" } - #generate warningblocks for each triggered Tcl bug in namespace ::punk::lib::check - set bugcheck_procs [info procs ::punk::lib::check::has_tclbug*] + #generate warningblocks for each triggered bug check in namespace ::punk::lib::check + #has_tclbug_* = Tcl core bugs; has_libbug_* = bundled/vendored library bugs (e.g. tcludp - G-036) + set bugcheck_procs [concat\ + [info procs ::punk::lib::check::has_tclbug*]\ + [info procs ::punk::lib::check::has_libbug*]\ + ] foreach bp $bugcheck_procs { set buginfo [$bp] if {[dict get $buginfo bug]} { @@ -8595,12 +8617,15 @@ namespace eval punk { major {set highlight [punk::ansi::a+ red bold]} default {set highlight ""} } + set indent " " append warningblock \n $highlight "warning level: $level $bp triggered." if {[dict exists $buginfo description]} { - set indent " " append warningblock \n "[punk::lib::indent [dict get $buginfo description] $indent]" } - if {[dict exists $buginfo bugref] && [dict get $buginfo bugref] ne ""} { + if {[dict exists $buginfo url] && [dict get $buginfo url] ne ""} { + #full reference url (e.g. non tcl-core trackers such as tcludp) + append warningblock \n "${indent}see [punk::ansi::hyperlink [dict get $buginfo url]]" + } elseif {[dict exists $buginfo bugref] && [dict get $buginfo bugref] ne ""} { set bugref [dict get $buginfo bugref] append warningblock \n "${indent}see [punk::ansi::hyperlink https://core.tcl-lang.org/tcl/tktview/$bugref]" } @@ -8622,7 +8647,12 @@ namespace eval punk { punk::args::define { @id -id ::punk::helptopic::env - @cmd -name "help env" -summary "punkshell environment vars." -help "Show punk-related and other relevant environment variables with their current values." + @cmd -name "help env"\ + -summary\ + "punkshell environment vars."\ + -help\ + "Show punk-related and other relevant environment + variables with their current values." @values -min 0 -max 0 } proc env {context args} { @@ -8723,7 +8753,14 @@ namespace eval punk { punk::args::define { @id -id ::punk::helptopic::console - @cmd -name "help console" -summary "Console behaviour tests and warnings." -help "Run some console/terminal behaviour tests (control string hiding, grapheme cluster support, cursor position query timing) and report warnings. Requires a responsive interactive console." + @cmd -name "help console"\ + -summary\ + "Console behaviour tests and warnings."\ + -help\ + "Run some console/terminal behaviour tests (control + string hiding, grapheme cluster support, cursor + position query timing) and report warnings. + Requires a responsive interactive console." @values -min 0 -max 0 } proc console {context args} { @@ -9350,7 +9387,7 @@ punkcheck::cli set_alias punkcheck package provide punk [namespace eval punk { #FUNCTL variable version - set version 0.2.0 + set version 0.2.2 }] diff --git a/src/vfs/_vfscommon.vfs/modules/punk/lib-0.2.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/lib-0.3.0.tm similarity index 99% rename from src/vfs/_vfscommon.vfs/modules/punk/lib-0.2.1.tm rename to src/vfs/_vfscommon.vfs/modules/punk/lib-0.3.0.tm index 27aa0795..09da6c9a 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/lib-0.2.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/lib-0.3.0.tm @@ -8,7 +8,7 @@ # (C) 2024 # # @@ Meta Begin -# Application punk::lib 0.2.1 +# Application punk::lib 0.3.0 # Meta platform tcl # Meta license BSD # @@ Meta End @@ -18,7 +18,7 @@ # doctools header # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ #*** !doctools -#[manpage_begin punkshell_module_punk::lib 0 0.2.1] +#[manpage_begin punkshell_module_punk::lib 0 0.3.0] #[copyright "2024"] #[titledesc {punk general utility functions}] [comment {-- Name section and table of contents description --}] #[moddesc {punk library}] [comment {-- Description at end of page heading --}] @@ -250,6 +250,56 @@ tcl::namespace::eval punk::lib::check { return [dict create bug $bug bugref e38dc74e2 description $description level medium] } + #has_libbug_* procs report bugs in bundled/vendored library packages rather than the Tcl core. + #They are surfaced through the same 'help tcl' warning report as the has_tclbug_* checks. + + #pure classifier, separated for testability - facts in, verdict out + proc libbug_udp_threadexit_applies {udpversion platform tclversion} { + if {$udpversion eq ""} { + return 0 ;#no udp package known - nothing vulnerable to load + } + if {$platform ne "windows"} { + return 0 + } + if {![package vsatisfies $tclversion 9]} { + #tcl 8.6 exhibited apparent immunity in the G-036 investigation (unexplained - see goal detail) + #detection deliberately scoped to Tcl 9 per G-036 acceptance + return 0 + } + return [expr {[package vcompare $udpversion 1.0.13] < 0}] + } + proc has_libbug_udp_threadexit {} { + #tcludp <= 1.0.12 on Windows: the per-thread exit handler UDP_ExitProc closes the + #PROCESS-GLOBAL sockListLock/waitForSock event handles. The first udp-loaded thread to + #exit corrupts the lock for every other udp-loaded thread - their event loops block + #forever in WaitForSingleObject on a dead or recycled handle (timers and thread::send + #unserviced). In punkshell the visible casualty is syslog log workers silently freezing + #(the original exit/quit hang this caused is separately mitigated). Root-caused + #2026-07-08 - see goal G-036 detail. Fixed upstream in tcludp 1.0.13 (per-thread + #UdpThreadExitProc deletes only the event source; ExitSockets closes the events at + #process exit). + #Version-based detection only (per G-036 acceptance) - no behavioural probe. + set udpversion [package provide udp] + if {$udpversion eq ""} { + #not loaded - determine what version would be provided, without loading the binary: + #an unsatisfiable require triggers the package unknown scan (registering ifneeded + #scripts) then fails before any dll load. + catch {package require udp 999999} + set available [package versions udp] + if {[llength $available]} { + set udpversion [lindex [lsort -command {package vcompare} $available] end] + } + } + set bug [libbug_udp_threadexit_applies $udpversion $::tcl_platform(platform) [package provide Tcl]] + if {$udpversion eq ""} { + set verinfo "no udp package found" + } else { + set verinfo "udp $udpversion" + } + set description "tcludp < 1.0.13 on Tcl 9 Windows ($verinfo): the udp package's per-thread exit\nhandler closes process-global event handles - after any udp-using thread exits, every\nother udp-using thread's event loop can freeze silently (e.g. syslog log workers stop).\nUpgrade the bundled/available udp package to 1.0.13+ (see goal G-036)." + return [dict create bug $bug bugref "" url https://core.tcl-lang.org/tcludp description $description level medium libversion $udpversion] + } + proc has_tclbug_safeinterp_compile {{show 0}} { #ensemble calls within safe interp not compiled #https://core.tcl-lang.org/tcl/tktview/1095bf7f756f9aed6bde @@ -9069,7 +9119,7 @@ namespace eval ::punk::args::register { package provide punk::lib [tcl::namespace::eval punk::lib { variable pkg punk::lib variable version - set version 0.2.1 + set version 0.3.0 }] return