From 440cc39073e8e5a1c9dd1b4c7294e1830f68155e Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Fri, 10 Jul 2026 20:26:24 +1000 Subject: [PATCH] update vfs: _vfscommon.vfs punk::lib 0.4.0, punk::repl 0.3.0, punk::packagepreference 0.2.0, shellthread 1.7.0 punkcheck-managed vfscommonupdate regeneration propagating the G-058 module releases into _vfscommon.vfs/modules. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- .../punk/{lib-0.3.1.tm => lib-0.4.0.tm} | 44 +++++++++++++++++-- ...ce-0.1.1.tm => packagepreference-0.2.0.tm} | 31 +++++++++++-- .../punk/{repl-0.2.2.tm => repl-0.3.0.tm} | 18 +++++++- ...llthread-1.6.3.tm => shellthread-1.7.0.tm} | 19 +++++++- 4 files changed, 102 insertions(+), 10 deletions(-) rename src/vfs/_vfscommon.vfs/modules/punk/{lib-0.3.1.tm => lib-0.4.0.tm} (99%) rename src/vfs/_vfscommon.vfs/modules/punk/{packagepreference-0.1.1.tm => packagepreference-0.2.0.tm} (92%) rename src/vfs/_vfscommon.vfs/modules/punk/{repl-0.2.2.tm => repl-0.3.0.tm} (99%) rename src/vfs/_vfscommon.vfs/modules/{shellthread-1.6.3.tm => shellthread-1.7.0.tm} (97%) diff --git a/src/vfs/_vfscommon.vfs/modules/punk/lib-0.3.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/lib-0.4.0.tm similarity index 99% rename from src/vfs/_vfscommon.vfs/modules/punk/lib-0.3.1.tm rename to src/vfs/_vfscommon.vfs/modules/punk/lib-0.4.0.tm index 1d460801..af1b9541 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/lib-0.3.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/lib-0.4.0.tm @@ -8,7 +8,7 @@ # (C) 2024 # # @@ Meta Begin -# Application punk::lib 0.3.1 +# Application punk::lib 0.4.0 # Meta platform tcl # Meta license BSD # @@ Meta End @@ -18,7 +18,7 @@ # doctools header # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ #*** !doctools -#[manpage_begin punkshell_module_punk::lib 0 0.3.1] +#[manpage_begin punkshell_module_punk::lib 0 0.4.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 --}] @@ -8197,6 +8197,12 @@ namespace eval punk::lib { is used, in which case punk::libunknown is sourced from the tm paths that were already set up by the earlier part of the script. + When the kit boot captured runtime static/builtin packages + (::punkboot::static_packages - see punk_main.tcl), the script also copies + that baseline and seeds 'package ifneeded {load {} }' + entries so statically-linked packages (e.g Thread/twapi on a tcl-sfe + runtime) resolve in the target. + See also: punk::lib::interp_sync_package_paths" @opts -libunknown -type boolean -default 0 -help\ @@ -8235,6 +8241,18 @@ namespace eval punk::lib { append script "tcl::tm::add \{*\}\[list [lreverse $tmlist]\]\n" append script "set ::auto_path \[list $ap\]\n" append script "package prefer $prefer\n" + #G-058: propagate runtime static/builtin package mappings captured at kit boot + #(see punk_main.tcl) so 'package require' of a statically-linked package (e.g + #Thread/twapi on a tcl-sfe runtime) resolves in the new thread/interp even though + #no pkgIndex for it exists on the (replaced) package search paths. + if {[info exists ::punkboot::static_packages] && [dict size $::punkboot::static_packages]} { + append script "namespace eval ::punkboot {}\n" + append script [list set ::punkboot::static_prefixes $::punkboot::static_prefixes] \n + append script [list set ::punkboot::static_packages $::punkboot::static_packages] \n + dict for {pkgname pinfo} $::punkboot::static_packages { + append script "if \{\[package provide [list $pkgname]\] eq \"\"\} \{[list package ifneeded $pkgname [dict get $pinfo version] [list load {} [dict get $pinfo prefix]]]\}\n" + } + } if {$do_libunknown} { if {[info exists ::punk::libunknown::epoch]} { append script "namespace eval ::punk::libunknown {}\n" @@ -8299,6 +8317,12 @@ namespace eval punk::lib { package unknown handler and scan cache as the parent. This is recommended when the child will do significant package loading. + When the kit boot captured runtime static/builtin packages + (::punkboot::static_packages - see punk_main.tcl), the child also receives + that baseline plus 'package ifneeded {load {} }' + seeding so statically-linked packages (e.g Thread/twapi on a tcl-sfe + runtime) resolve in the child. + This is an opt-in helper — call sites that don't use it keep their current behavior. It does not load packages, install punk::packagepreference, share channels, or configure safe-interp restrictions — those remain caller @@ -8340,6 +8364,20 @@ namespace eval punk::lib { interp eval $interp {tcl::tm::remove {*}[tcl::tm::list]} interp eval $interp [list tcl::tm::add {*}[lreverse [tcl::tm::list]]] interp eval $interp [list package prefer [package prefer]] + #G-058: propagate runtime static/builtin package mappings captured at kit boot + #(see punk_main.tcl) so 'package require' of a statically-linked package (e.g + #Thread/twapi on a tcl-sfe runtime) resolves in the child interp even though no + #pkgIndex for it exists on the (replaced) package search paths. + if {[info exists ::punkboot::static_packages] && [dict size $::punkboot::static_packages]} { + interp eval $interp [list namespace eval ::punkboot {}] + interp eval $interp [list set ::punkboot::static_prefixes $::punkboot::static_prefixes] + interp eval $interp [list set ::punkboot::static_packages $::punkboot::static_packages] + dict for {pkgname pinfo} $::punkboot::static_packages { + if {[interp eval $interp [list package provide $pkgname]] eq ""} { + interp eval $interp [list package ifneeded $pkgname [dict get $pinfo version] [list load {} [dict get $pinfo prefix]]] + } + } + } #extended: copy epoch + source libunknown + call init if {$do_libunknown} { if {[info exists ::punk::libunknown::epoch]} { @@ -9135,7 +9173,7 @@ namespace eval ::punk::args::register { package provide punk::lib [tcl::namespace::eval punk::lib { variable pkg punk::lib variable version - set version 0.3.1 + set version 0.4.0 }] return diff --git a/src/vfs/_vfscommon.vfs/modules/punk/packagepreference-0.1.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/packagepreference-0.2.0.tm similarity index 92% rename from src/vfs/_vfscommon.vfs/modules/punk/packagepreference-0.1.1.tm rename to src/vfs/_vfscommon.vfs/modules/punk/packagepreference-0.2.0.tm index 8ad1d774..48713fce 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/packagepreference-0.1.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/packagepreference-0.2.0.tm @@ -8,7 +8,7 @@ # (C) 2024 # # @@ Meta Begin -# Application punk::packagepreference 0.1.1 +# Application punk::packagepreference 0.2.0 # Meta platform tcl # Meta license # @@ Meta End @@ -18,7 +18,7 @@ # doctools header # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ #*** !doctools -#[manpage_begin punkshell_module_punk::packagepreference 0 0.1.1] +#[manpage_begin punkshell_module_punk::packagepreference 0 0.2.0] #[copyright "2024"] #[titledesc {punkshell package/module loading}] [comment {-- Name section and table of contents description --}] #[moddesc {package/module load}] [comment {-- Description at end of page heading --}] @@ -171,6 +171,24 @@ tcl::namespace::eval punk::packagepreference { return [uplevel 1 [list $COMMANDSTACKNEXT {*}$args]] } + #G-058 static-vs-bundled policy for runtime static/builtin packages + #(baseline captured at kit boot into ::punkboot::static_packages - see punk_main.tcl). + #Ensure the static mapping exists in this interp (seeding is normally done at + #interp/thread creation - this covers stragglers), then trigger the package + #unknown index scan so any bundled vfs/module copies are ALSO registered before + #resolution. With all candidates registered, standard resolution compares + #versions (highest acceptable wins) - a static copy is not blindly masked by an + #older bundled dll, and a genuinely newer bundled copy remains reachable. + #(On identical versions the bundled copy's ifneeded entry, registered by the + # later scan, wins - same version either way.) + if {[info exists ::punkboot::static_packages] && [dict exists $::punkboot::static_packages $pkg]} { + set spinfo [dict get $::punkboot::static_packages $pkg] + if {[dict get $spinfo version] ni [$COMMANDSTACKNEXT_ORIGINAL versions $pkg]} { + $COMMANDSTACKNEXT_ORIGINAL ifneeded $pkg [dict get $spinfo version] [list load {} [dict get $spinfo prefix]] + } + catch {uplevel 1 [list {*}[$COMMANDSTACKNEXT_ORIGINAL unknown] $pkg]} + } + if {!$is_exact && [llength $vwant] <= 1 } { #required version unspecified - or specified singularly set available_versions [$COMMANDSTACKNEXT_ORIGINAL versions $pkg] @@ -179,7 +197,12 @@ tcl::namespace::eval punk::packagepreference { #An attempt to detect dll/so loaded and try to load same version #dll/so files are often named with version numbers that don't contain dots or a version number at all #e.g sqlite3400.dll Thread288.dll - set pkgloadedinfo [lsearch -nocase -inline -index 1 [info loaded] $pkg] + #G-058: exclude empty-filename entries - those are static REGISTRATIONS + #(process-global, not necessarily loaded anywhere) and forcing their + #version here would defeat the version-aware static-vs-bundled policy + #above (e.g pinning to the static version even when a bundled copy is + #genuinely newer) + set pkgloadedinfo [lsearch -nocase -inline -index 1 [lsearch -all -inline -not -exact -index 0 [info loaded] {}] $pkg] if {[llength $pkgloadedinfo]} { if {[llength $available_versions] > 1} { @@ -489,7 +512,7 @@ namespace eval ::punk::args::register { package provide punk::packagepreference [tcl::namespace::eval punk::packagepreference { variable pkg punk::packagepreference variable version - set version 0.1.1 + set version 0.2.0 }] return diff --git a/src/vfs/_vfscommon.vfs/modules/punk/repl-0.2.2.tm b/src/vfs/_vfscommon.vfs/modules/punk/repl-0.3.0.tm similarity index 99% rename from src/vfs/_vfscommon.vfs/modules/punk/repl-0.2.2.tm rename to src/vfs/_vfscommon.vfs/modules/punk/repl-0.3.0.tm index 355c9abf..151c8af8 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/repl-0.2.2.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/repl-0.3.0.tm @@ -3241,6 +3241,8 @@ namespace eval repl { } %autopath% [list $::auto_path] {*}{ } %lib_epoch% [list $::punk::libunknown::epoch] {*}{ } %packageprefer% [list [package prefer]] {*}{ + } %staticprefixes% [list [expr {[info exists ::punkboot::static_prefixes] ? $::punkboot::static_prefixes : ""}]] {*}{ + } %staticpackages% [list [expr {[info exists ::punkboot::static_packages] ? $::punkboot::static_packages : ""}]] {*}{ } ] #scriptmap applied at end to satisfy silly editor highlighting. @@ -3256,6 +3258,20 @@ namespace eval repl { #It will also need to be added in that interp set ::auto_path %autopath% package prefer %packageprefer% + #G-058: runtime static/builtin package baseline captured at kit boot (punk_main.tcl). + #Make it available in this codethread and seed ifneeded mappings so statically-linked + #packages (e.g Thread/twapi on a tcl-sfe runtime) resolve here - and so + #punk::lib::interp_sync_package_paths can propagate the same into the code interp. + namespace eval ::punkboot {} + set ::punkboot::static_prefixes %staticprefixes% + set ::punkboot::static_packages %staticpackages% + if {[dict size $::punkboot::static_packages]} { + dict for {pkgname pinfo} $::punkboot::static_packages { + if {[package provide $pkgname] eq ""} { + package ifneeded $pkgname [dict get $pinfo version] [list load {} [dict get $pinfo prefix]] + } + } + } set tclmajorv [lindex [split [tcl::info::tclversion] .] 0] #jmn #puts stdout "CODETHREAD tm list" @@ -4215,7 +4231,7 @@ namespace eval repl { } package provide punk::repl [namespace eval punk::repl { variable version - set version 0.2.2 + set version 0.3.0 }] #repl::start $program_read_stdin_pipe diff --git a/src/vfs/_vfscommon.vfs/modules/shellthread-1.6.3.tm b/src/vfs/_vfscommon.vfs/modules/shellthread-1.7.0.tm similarity index 97% rename from src/vfs/_vfscommon.vfs/modules/shellthread-1.6.3.tm rename to src/vfs/_vfscommon.vfs/modules/shellthread-1.7.0.tm index cd0c83c6..ea0b8ce6 100644 --- a/src/vfs/_vfscommon.vfs/modules/shellthread-1.6.3.tm +++ b/src/vfs/_vfscommon.vfs/modules/shellthread-1.7.0.tm @@ -617,7 +617,9 @@ namespace eval shellthread::manager { #set ts_start [::shellthread::iso8601] set tidworker [thread::create -preserved] - set init_script [string map [list %ts_start% $ts_start %mp% [tcl::tm::list] %ap% $::auto_path %tidcli% $tidclient %sd% $settingsdict] { + set static_prefixes [expr {[info exists ::punkboot::static_prefixes] ? $::punkboot::static_prefixes : ""}] + set static_packages [expr {[info exists ::punkboot::static_packages] ? $::punkboot::static_packages : ""}] + set init_script [string map [list %ts_start% $ts_start %mp% [tcl::tm::list] %ap% $::auto_path %tidcli% $tidclient %sd% $settingsdict %spfx% [list $static_prefixes] %spkg% [list $static_packages]] { #set tclbase [file dirname [file dirname [info nameofexecutable]]] #set tcllib $tclbase/lib #if {$tcllib ni $::auto_path} { @@ -642,6 +644,19 @@ namespace eval shellthread::manager { set ::auto_path [dict get $::settingsinfo auto_path] } + #G-058: runtime static/builtin package baseline captured at kit boot (punk_main.tcl) + #seed ifneeded mappings so statically-linked packages resolve in this worker + namespace eval ::punkboot {} + set ::punkboot::static_prefixes %spfx% + set ::punkboot::static_packages %spkg% + if {[dict size $::punkboot::static_packages]} { + dict for {pkgname pinfo} $::punkboot::static_packages { + if {[package provide $pkgname] eq ""} { + package ifneeded $pkgname [dict get $pinfo version] [list load {} [dict get $pinfo prefix]] + } + } + } + package require punk::packagepreference punk::packagepreference::install @@ -973,7 +988,7 @@ namespace eval shellthread::manager { package provide shellthread [namespace eval shellthread { variable version - set version 1.6.3 + set version 1.7.0 }]