Browse Source

punk-runtime: toml-aware list -remote for the published family artifacts

Publication side-effects handled ahead of the punkbin push (b5c258f
there - first family -r1 artifacts + metadata + defaults flip to
tclsh9.0.5-punk-r1.exe):

- remote-only rows skip support files (the six metadata tomls now ride
  in the server's sha1sums beside the runtimes; same extension set as
  the local candidate filter).
- the '(= server default)' active marker also matches via the active's
  beside-toml artifact identity: the default names an immutable -r<N>
  artifact while the active is typically its materialized WORKING name,
  so exact-name matching alone would never fire post-family.

Live-verified against the pushed server: no-name fetch resolves
tclsh9.0.5-punk-r1.exe + metadata; list -remote shows all three -r1
artifacts Same version, the default row marked, active
tclsh9.0.5-punk.exe annotated '(= server default)' through its toml
identity, and no toml leakage. G-067 note records publication done
(r1 immutable - next republish takes -Dfamilyrev=2). Rewrapped;
roundtrip pin PASS; layout copy refreshed. Project 0.18.8.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 1 week ago
parent
commit
a76e73db31
  1. 4
      CHANGELOG.md
  2. 38
      bin/punk-runtime.cmd
  3. 18
      goals/G-067-module-artifact-channel.md
  4. 2
      punkproject.toml
  5. 38
      src/project_layouts/vendor/punk/project-0.1/bin/punk-runtime.cmd
  6. 19
      src/scriptapps/bin/punk-runtime.bash
  7. 19
      src/scriptapps/bin/punk-runtime.ps1

4
CHANGELOG.md

@ -5,6 +5,10 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to
Entries are newest-first; one bullet per notable change. See the root `AGENTS.md` Entries are newest-first; one bullet per notable change. See the root `AGENTS.md`
"Project Versioning" section for the bump policy. "Project Versioning" section for the bump policy.
## [0.18.8] - 2026-07-22
- `bin/punk-runtime.cmd` `list -remote`: remote-only rows skip support files (artifact metadata tomls etc now ride in the server's sha1sums beside runtimes - same extension set the local candidate filter excludes); the `(= server default)` active marker also recognizes a materialized working copy via its beside-toml artifact identity (the default names an immutable `-r<N>` artifact while the active is typically its working name - exact-name matching alone would never fire post-family). Verified live against the first published family artifacts.
## [0.18.7] - 2026-07-22 ## [0.18.7] - 2026-07-22
- `bin/punk-runtime.cmd`: deterministic listing order everywhere. Investigation of an ordering discrepancy between launch paths found two edition divergences: the `.ps1` twin runs under the INVOKING powershell (pwsh 7) while the `.cmd` routes via wrap-pinned Windows PowerShell 5, and both Hashtable enumeration order AND culture-sensitive `Sort-Object` collation (NLS vs ICU) differ between those editions. All name orderings now use ordinal comparison (ps1) / `LC_ALL=C` (bash), which agree byte-for-byte across pwsh, powershell and bash. Also corrected `bin/AGENTS.md`: the `.ps1` twin is SELF-MATERIALIZED by the polyglot's batch layer (created when missing, `fc`-compared and re-copied when stale) - the previous "refresh both on re-wrap" manual-copy guidance was stale; twin verified regenerating byte-identical after deletion. - `bin/punk-runtime.cmd`: deterministic listing order everywhere. Investigation of an ordering discrepancy between launch paths found two edition divergences: the `.ps1` twin runs under the INVOKING powershell (pwsh 7) while the `.cmd` routes via wrap-pinned Windows PowerShell 5, and both Hashtable enumeration order AND culture-sensitive `Sort-Object` collation (NLS vs ICU) differ between those editions. All name orderings now use ordinal comparison (ps1) / `LC_ALL=C` (bash), which agree byte-for-byte across pwsh, powershell and bash. Also corrected `bin/AGENTS.md`: the `.ps1` twin is SELF-MATERIALIZED by the polyglot's batch layer (created when missing, `fc`-compared and re-copied when stale) - the previous "refresh both on re-wrap" manual-copy guidance was stale; twin verified regenerating byte-identical after deletion.

38
bin/punk-runtime.cmd

@ -1747,8 +1747,19 @@ case "$action" in
echo "server default for $archtail: $platform_default" echo "server default for $archtail: $platform_default"
fi fi
if [[ -n "$activename" ]]; then if [[ -n "$activename" ]]; then
#the default names an immutable -r<N> ARTIFACT while the active is
#typically its materialized WORKING name - the beside-toml's 'name'
#field records which artifact the working copy came from, so match
#on either identity
active_artifact=""
activetoml="$archdir/$(rootname_of "$activename").toml"
if [[ -f "$activetoml" ]]; then
active_artifact=$(sed -n 's/^[[:space:]]*name[[:space:]]*=[[:space:]]*"\(.*\)".*/\1/p' "$activetoml" | head -n 1)
fi
matchnote="" matchnote=""
[[ -n "$platform_default" && "$activename" == "$platform_default" ]] && matchnote=" (= server default)" if [[ -n "$platform_default" ]] && [[ "$activename" == "$platform_default" || "$active_artifact" == "$platform_default" ]]; then
matchnote=" (= server default)"
fi
echo "active (local): $activename$matchnote" echo "active (local): $activename$matchnote"
fi fi
echo "-----------------------------------------------------------------------" echo "-----------------------------------------------------------------------"
@ -1775,6 +1786,12 @@ case "$action" in
#mode but bash read does not - without this a locally-present runtime #mode but bash read does not - without this a locally-present runtime
#also shows as a remote-only row (\r-suffixed name fails the -f test) #also shows as a remote-only row (\r-suffixed name fails the -f test)
tr -d '\r' < "$sha1local" | sed -n 's/^[0-9a-fA-F]\{40\} \*\(.*\)$/\1/p' | LC_ALL=C sort | while IFS= read -r rname; do tr -d '\r' < "$sha1local" | sed -n 's/^[0-9a-fA-F]\{40\} \*\(.*\)$/\1/p' | LC_ALL=C sort | while IFS= read -r rname; do
#skip support files riding in the server's sha1sums beside the
#runtimes (artifact metadata tomls etc) - same extension set the
#local candidate filter excludes
case "$rname" in
*.txt|*.toml|*.tm|*.tmp|*.log) continue;;
esac
if [[ -n "$rname" && ! -f "$archdir/$rname" ]]; then if [[ -n "$rname" && ! -f "$archdir/$rname" ]]; then
annot="" annot=""
[[ -n "$platform_default" && "$rname" == "$platform_default" ]] && annot=" (server default)" [[ -n "$platform_default" && "$rname" == "$platform_default" ]] && annot=" (server default)"
@ -3063,8 +3080,20 @@ function psmain {
Write-host "server default for ${arch}: $platform_default" Write-host "server default for ${arch}: $platform_default"
} }
if ($activename -ne "") { if ($activename -ne "") {
#the default names an immutable -r<N> ARTIFACT while the active
#is typically its materialized WORKING name - the beside-toml's
#'name' field records which artifact the working copy came from,
#so match on either identity
$active_artifact = ""
$activetoml = Join-Path -Path $archfolder -ChildPath ((Get-PunkRuntimeRootName $activename) + ".toml")
if (Test-Path -Path $activetoml -PathType Leaf) {
foreach ($tline in (Get-Content -Path $activetoml)) {
$m = [regex]::Match($tline, '^\s*name\s*=\s*"(.*)"\s*$')
if ($m.Success) { $active_artifact = $m.Groups[1].Value; break }
}
}
$matchnote = "" $matchnote = ""
if ($platform_default -ne "" -and $activename -eq $platform_default) { if ($platform_default -ne "" -and ($activename -eq $platform_default -or $active_artifact -eq $platform_default)) {
$matchnote = " (= server default)" $matchnote = " (= server default)"
} }
Write-host "active (local): $activename$matchnote" Write-host "active (local): $activename$matchnote"
@ -3113,6 +3142,11 @@ function psmain {
[array]::Sort($remotekeys, [System.StringComparer]::Ordinal) [array]::Sort($remotekeys, [System.StringComparer]::Ordinal)
foreach ($key in $remotekeys) { foreach ($key in $remotekeys) {
if (-not ($localdict.ContainsKey($key))) { if (-not ($localdict.ContainsKey($key))) {
#skip support files riding in the server's sha1sums beside
#the runtimes (artifact metadata tomls etc) - same extension
#set the local candidate filter excludes
$rext = [System.IO.Path]::GetExtension($key)
if ($(".txt",".toml",".tm",".tmp",".log") -contains $rext) { continue }
$annot = "" $annot = ""
if ($platform_default -ne "" -and $key -eq $platform_default) { $annot = " (server default)" } if ($platform_default -ne "" -and $key -eq $platform_default) { $annot = " (server default)" }
write-host -nonewline " $lhs_missing" write-host -nonewline " $lhs_missing"

18
goals/G-067-module-artifact-channel.md

@ -44,14 +44,16 @@ and pull (G-065) instead of re-vendoring by hand.
(punkshell-only, must be documented). Generation + multi-name discovery detail: (punkshell-only, must be documented). Generation + multi-name discovery detail:
G-066 Notes. G-066 Notes.
- 2026-07-22 (from archived G-103 - see goals/archive/G-103-runtime-kit-family.md): - 2026-07-22 (from archived G-103 - see goals/archive/G-103-runtime-kit-family.md):
the family runtime -rN artifacts + toml metadata + sha1sums now EXIST the family runtime -rN artifacts + toml metadata are PUBLISHED (2026-07-22,
(suite kit-family-artifacts emission, punkbin-layout shaped) and their punkbin user-directed; punkbin b5c258f pushed): tclsh9.0.5-r1/-punk-r1/-punk-bi-r1
publication is a pending USER-GATED step - the archived goal's deferral .exe+.toml in win32-x86_64/, sha1sums regenerated, defaults.txt flipped to
condition ("publication follows this goal's artifacts") is satisfied. When it tclsh9.0.5-punk-r1.exe in the same change-set (the recorded release process,
happens: copy the emission into punkbin win32-x86_64/, run build_sha1sums.tcl, exercised for real). r1 is now immutable - republishing those (patchlevel,
flip defaults.txt's win32-x86_64 line in the same change-set (the recorded variant) pairs needs -Dfamilyrev=2. Live-verified: no-name fetch resolves the
release process). Those runtime artifacts are punkbin's FIRST metadata-carrying new default with metadata; list -remote marks the default row and recognizes
class; this goal's library class follows the same per-platform + toml pattern. the materialized active via its toml artifact identity. These runtime
artifacts are punkbin's FIRST metadata-carrying class; this goal's library
class follows the same per-platform + toml pattern.
- 2026-07-22 (user framing): the zig BUILDSUITES are a producing source for this - 2026-07-22 (user framing): the zig BUILDSUITES are a producing source for this
channel - libraries the suites build (thread/tk/tcltls-class) get packaged as channel - libraries the suites build (thread/tk/tcltls-class) get packaged as
per-platform .tm/pkg artifacts when they are not going directly into a kit, and per-platform .tm/pkg artifacts when they are not going directly into a kit, and

2
punkproject.toml

@ -1,4 +1,4 @@
[project] [project]
name = "punkshell" name = "punkshell"
version = "0.18.7" version = "0.18.8"
license = "BSD-2-Clause" license = "BSD-2-Clause"

38
src/project_layouts/vendor/punk/project-0.1/bin/punk-runtime.cmd vendored

@ -1747,8 +1747,19 @@ case "$action" in
echo "server default for $archtail: $platform_default" echo "server default for $archtail: $platform_default"
fi fi
if [[ -n "$activename" ]]; then if [[ -n "$activename" ]]; then
#the default names an immutable -r<N> ARTIFACT while the active is
#typically its materialized WORKING name - the beside-toml's 'name'
#field records which artifact the working copy came from, so match
#on either identity
active_artifact=""
activetoml="$archdir/$(rootname_of "$activename").toml"
if [[ -f "$activetoml" ]]; then
active_artifact=$(sed -n 's/^[[:space:]]*name[[:space:]]*=[[:space:]]*"\(.*\)".*/\1/p' "$activetoml" | head -n 1)
fi
matchnote="" matchnote=""
[[ -n "$platform_default" && "$activename" == "$platform_default" ]] && matchnote=" (= server default)" if [[ -n "$platform_default" ]] && [[ "$activename" == "$platform_default" || "$active_artifact" == "$platform_default" ]]; then
matchnote=" (= server default)"
fi
echo "active (local): $activename$matchnote" echo "active (local): $activename$matchnote"
fi fi
echo "-----------------------------------------------------------------------" echo "-----------------------------------------------------------------------"
@ -1775,6 +1786,12 @@ case "$action" in
#mode but bash read does not - without this a locally-present runtime #mode but bash read does not - without this a locally-present runtime
#also shows as a remote-only row (\r-suffixed name fails the -f test) #also shows as a remote-only row (\r-suffixed name fails the -f test)
tr -d '\r' < "$sha1local" | sed -n 's/^[0-9a-fA-F]\{40\} \*\(.*\)$/\1/p' | LC_ALL=C sort | while IFS= read -r rname; do tr -d '\r' < "$sha1local" | sed -n 's/^[0-9a-fA-F]\{40\} \*\(.*\)$/\1/p' | LC_ALL=C sort | while IFS= read -r rname; do
#skip support files riding in the server's sha1sums beside the
#runtimes (artifact metadata tomls etc) - same extension set the
#local candidate filter excludes
case "$rname" in
*.txt|*.toml|*.tm|*.tmp|*.log) continue;;
esac
if [[ -n "$rname" && ! -f "$archdir/$rname" ]]; then if [[ -n "$rname" && ! -f "$archdir/$rname" ]]; then
annot="" annot=""
[[ -n "$platform_default" && "$rname" == "$platform_default" ]] && annot=" (server default)" [[ -n "$platform_default" && "$rname" == "$platform_default" ]] && annot=" (server default)"
@ -3063,8 +3080,20 @@ function psmain {
Write-host "server default for ${arch}: $platform_default" Write-host "server default for ${arch}: $platform_default"
} }
if ($activename -ne "") { if ($activename -ne "") {
#the default names an immutable -r<N> ARTIFACT while the active
#is typically its materialized WORKING name - the beside-toml's
#'name' field records which artifact the working copy came from,
#so match on either identity
$active_artifact = ""
$activetoml = Join-Path -Path $archfolder -ChildPath ((Get-PunkRuntimeRootName $activename) + ".toml")
if (Test-Path -Path $activetoml -PathType Leaf) {
foreach ($tline in (Get-Content -Path $activetoml)) {
$m = [regex]::Match($tline, '^\s*name\s*=\s*"(.*)"\s*$')
if ($m.Success) { $active_artifact = $m.Groups[1].Value; break }
}
}
$matchnote = "" $matchnote = ""
if ($platform_default -ne "" -and $activename -eq $platform_default) { if ($platform_default -ne "" -and ($activename -eq $platform_default -or $active_artifact -eq $platform_default)) {
$matchnote = " (= server default)" $matchnote = " (= server default)"
} }
Write-host "active (local): $activename$matchnote" Write-host "active (local): $activename$matchnote"
@ -3113,6 +3142,11 @@ function psmain {
[array]::Sort($remotekeys, [System.StringComparer]::Ordinal) [array]::Sort($remotekeys, [System.StringComparer]::Ordinal)
foreach ($key in $remotekeys) { foreach ($key in $remotekeys) {
if (-not ($localdict.ContainsKey($key))) { if (-not ($localdict.ContainsKey($key))) {
#skip support files riding in the server's sha1sums beside
#the runtimes (artifact metadata tomls etc) - same extension
#set the local candidate filter excludes
$rext = [System.IO.Path]::GetExtension($key)
if ($(".txt",".toml",".tm",".tmp",".log") -contains $rext) { continue }
$annot = "" $annot = ""
if ($platform_default -ne "" -and $key -eq $platform_default) { $annot = " (server default)" } if ($platform_default -ne "" -and $key -eq $platform_default) { $annot = " (server default)" }
write-host -nonewline " $lhs_missing" write-host -nonewline " $lhs_missing"

19
src/scriptapps/bin/punk-runtime.bash

@ -467,8 +467,19 @@ case "$action" in
echo "server default for $archtail: $platform_default" echo "server default for $archtail: $platform_default"
fi fi
if [[ -n "$activename" ]]; then if [[ -n "$activename" ]]; then
#the default names an immutable -r<N> ARTIFACT while the active is
#typically its materialized WORKING name - the beside-toml's 'name'
#field records which artifact the working copy came from, so match
#on either identity
active_artifact=""
activetoml="$archdir/$(rootname_of "$activename").toml"
if [[ -f "$activetoml" ]]; then
active_artifact=$(sed -n 's/^[[:space:]]*name[[:space:]]*=[[:space:]]*"\(.*\)".*/\1/p' "$activetoml" | head -n 1)
fi
matchnote="" matchnote=""
[[ -n "$platform_default" && "$activename" == "$platform_default" ]] && matchnote=" (= server default)" if [[ -n "$platform_default" ]] && [[ "$activename" == "$platform_default" || "$active_artifact" == "$platform_default" ]]; then
matchnote=" (= server default)"
fi
echo "active (local): $activename$matchnote" echo "active (local): $activename$matchnote"
fi fi
echo "-----------------------------------------------------------------------" echo "-----------------------------------------------------------------------"
@ -495,6 +506,12 @@ case "$action" in
#mode but bash read does not - without this a locally-present runtime #mode but bash read does not - without this a locally-present runtime
#also shows as a remote-only row (\r-suffixed name fails the -f test) #also shows as a remote-only row (\r-suffixed name fails the -f test)
tr -d '\r' < "$sha1local" | sed -n 's/^[0-9a-fA-F]\{40\} \*\(.*\)$/\1/p' | LC_ALL=C sort | while IFS= read -r rname; do tr -d '\r' < "$sha1local" | sed -n 's/^[0-9a-fA-F]\{40\} \*\(.*\)$/\1/p' | LC_ALL=C sort | while IFS= read -r rname; do
#skip support files riding in the server's sha1sums beside the
#runtimes (artifact metadata tomls etc) - same extension set the
#local candidate filter excludes
case "$rname" in
*.txt|*.toml|*.tm|*.tmp|*.log) continue;;
esac
if [[ -n "$rname" && ! -f "$archdir/$rname" ]]; then if [[ -n "$rname" && ! -f "$archdir/$rname" ]]; then
annot="" annot=""
[[ -n "$platform_default" && "$rname" == "$platform_default" ]] && annot=" (server default)" [[ -n "$platform_default" && "$rname" == "$platform_default" ]] && annot=" (server default)"

19
src/scriptapps/bin/punk-runtime.ps1

@ -766,8 +766,20 @@ function psmain {
Write-host "server default for ${arch}: $platform_default" Write-host "server default for ${arch}: $platform_default"
} }
if ($activename -ne "") { if ($activename -ne "") {
#the default names an immutable -r<N> ARTIFACT while the active
#is typically its materialized WORKING name - the beside-toml's
#'name' field records which artifact the working copy came from,
#so match on either identity
$active_artifact = ""
$activetoml = Join-Path -Path $archfolder -ChildPath ((Get-PunkRuntimeRootName $activename) + ".toml")
if (Test-Path -Path $activetoml -PathType Leaf) {
foreach ($tline in (Get-Content -Path $activetoml)) {
$m = [regex]::Match($tline, '^\s*name\s*=\s*"(.*)"\s*$')
if ($m.Success) { $active_artifact = $m.Groups[1].Value; break }
}
}
$matchnote = "" $matchnote = ""
if ($platform_default -ne "" -and $activename -eq $platform_default) { if ($platform_default -ne "" -and ($activename -eq $platform_default -or $active_artifact -eq $platform_default)) {
$matchnote = " (= server default)" $matchnote = " (= server default)"
} }
Write-host "active (local): $activename$matchnote" Write-host "active (local): $activename$matchnote"
@ -816,6 +828,11 @@ function psmain {
[array]::Sort($remotekeys, [System.StringComparer]::Ordinal) [array]::Sort($remotekeys, [System.StringComparer]::Ordinal)
foreach ($key in $remotekeys) { foreach ($key in $remotekeys) {
if (-not ($localdict.ContainsKey($key))) { if (-not ($localdict.ContainsKey($key))) {
#skip support files riding in the server's sha1sums beside
#the runtimes (artifact metadata tomls etc) - same extension
#set the local candidate filter excludes
$rext = [System.IO.Path]::GetExtension($key)
if ($(".txt",".toml",".tm",".tmp",".log") -contains $rext) { continue }
$annot = "" $annot = ""
if ($platform_default -ne "" -and $key -eq $platform_default) { $annot = " (server default)" } if ($platform_default -ne "" -and $key -eq $platform_default) { $annot = " (server default)" }
write-host -nonewline " $lhs_missing" write-host -nonewline " $lhs_missing"

Loading…
Cancel
Save