Browse Source

punk-runtime fetch: materialization hint when the working name is absent; punkshell 0.30.4

Closes the observed UX gap (G-128 detail, program-files checkout findings):
fetch reports an active runtime, but bakes reference the suffixless WORKING
name that only 'use' materializes - so a first fetch left bakelist reading
runtime=missing with nothing pointing at the next step. Both payloads (ps1 +
bash, parity wording) now print
  note: bakes and projects reference <working> - materialize it with:
  punk-runtime use <artifact>
after fetching an -r<N> artifact whose working name is absent, and stay
silent once it exists (the downloads-never-bind rule is unchanged - fetch
still materializes nothing).

Sources edited under src/scriptapps/bin and bin/punk-runtime.cmd regenerated
via scriptwrap multishell (-force 1; checkfile ERROR-free, 4 normal
possibly-bogus warnings) - committed together per the wrap workflow;
runtimecmd_roundtrip byte-identity passes. New pin
runtimecmd_fetch_materialize_hint in runtimecmd_freshness.test (11/11, ~+5s:
hint present on both payloads via the fixture server, absent after use via
the cmd route). Live-verified against the real punkbin server from the
spaced test checkout: hint fires on the no-download path too, silent with
the working copy present.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 2 days ago
parent
commit
0e0a64eb23
  1. 10
      CHANGELOG.md
  2. 17
      bin/punk-runtime.cmd
  3. 10
      goals/G-128-portable-pe-resource-stamping.md
  4. 2
      punkproject.toml
  5. 7
      src/scriptapps/bin/punk-runtime.bash
  6. 10
      src/scriptapps/bin/punk-runtime.ps1
  7. 28
      src/tests/shell/testsuites/binscripts/runtimecmd_freshness.test

10
CHANGELOG.md

@ -5,6 +5,16 @@ 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`
"Project Versioning" section for the bump policy.
## [0.30.4] - 2026-07-29
- `punk-runtime fetch` now prints a one-line materialization hint when the
fetched `-rN` artifact's WORKING name (what mapvfs and bakes reference) is
absent: "note: bakes and projects reference <working> - materialize it
with: punk-runtime use <artifact>". Both payloads (ps1 + bash, parity
wording); silent once the working copy exists. Closes the surprise where
fetch reports an active runtime but `make.tcl bakelist` still reads
runtime=missing until `use` runs.
## [0.30.3] - 2026-07-29
- Fleet renamed: every win32 kit now carries the embedded `PUNKSHELL` group

17
bin/punk-runtime.cmd

@ -1861,6 +1861,13 @@ case "$action" in
echo "no artifact metadata toml on server for $runtime (ok for pre-family runtimes)"
fi
fi
#G-128 follow-through: a fetched -r<N> artifact is not what bakes wrap -
#mapvfs and generated projects reference the WORKING name, which only
#'use' materializes. One line while that gap exists.
fetched_working="$(working_name_of "$runtime")"
if [[ -n "$fetched_working" && ! -f "${archdir}/${fetched_working}" ]]; then
echo "note: bakes and projects reference ${fetched_working} - materialize it with: punk-runtime use ${runtime}"
fi
#first fetch establishes the active runtime; later fetches never steal it
if [[ -z "$(get_active)" ]]; then
set_active "$runtime"
@ -3478,6 +3485,16 @@ function psmain {
Write-Host "no artifact metadata toml on server for $runtime (ok for pre-family runtimes)"
}
}
#G-128 follow-through: a fetched -r<N> artifact is not what bakes
#wrap - mapvfs and generated projects reference the WORKING name,
#which only 'use' materializes. One line while that gap exists.
$fm = [regex]::Match($runtime, '^(.*)-r([0-9]+)(\.[Ee][Xx][Ee])?$')
if ($fm.Success) {
$fetchedworking = $fm.Groups[1].Value + $fm.Groups[3].Value
if (-not (Test-Path -Path (Join-Path -Path $archfolder -ChildPath $fetchedworking) -PathType Leaf)) {
Write-Host "note: bakes and projects reference $fetchedworking - materialize it with: punk-runtime use $runtime"
}
}
#first fetch establishes the active runtime; later fetches never steal it
if ((Get-PunkActiveRuntime $archfolder) -eq "") {
Set-PunkActiveRuntime $archfolder $runtime

10
goals/G-128-portable-pe-resource-stamping.md

@ -361,5 +361,11 @@ the parked RT_VERSION stamping wants, since the project version is known late.
even though it lists it as a candidate). Until then bakelist rows read
runtime=missing; the `deployed` column is the KIT build/deploy state
(absent in a fresh checkout is correct). Candidates flagged to the user:
suffixless `use` materializing from a sole matching -rN artifact, and/or
fetch hinting the `use` step for the platform default.
(a) fetch hinting the `use` step - IMPLEMENTED 2026-07-29 (user-directed,
punkshell 0.30.4): both punk-runtime payloads print "note: bakes and
projects reference <working> - materialize it with: punk-runtime use
<artifact>" when a fetched -rN artifact's working name is absent, silent
otherwise; pinned by runtimecmd_fetch_materialize_hint (both payloads via
the httpfixture server) and live-verified against the real punkbin server
from the spaced checkout; (b) suffixless `use` materializing from a sole
matching -rN artifact - still open, user-owned.

2
punkproject.toml

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

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

@ -581,6 +581,13 @@ case "$action" in
echo "no artifact metadata toml on server for $runtime (ok for pre-family runtimes)"
fi
fi
#G-128 follow-through: a fetched -r<N> artifact is not what bakes wrap -
#mapvfs and generated projects reference the WORKING name, which only
#'use' materializes. One line while that gap exists.
fetched_working="$(working_name_of "$runtime")"
if [[ -n "$fetched_working" && ! -f "${archdir}/${fetched_working}" ]]; then
echo "note: bakes and projects reference ${fetched_working} - materialize it with: punk-runtime use ${runtime}"
fi
#first fetch establishes the active runtime; later fetches never steal it
if [[ -z "$(get_active)" ]]; then
set_active "$runtime"

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

@ -848,6 +848,16 @@ function psmain {
Write-Host "no artifact metadata toml on server for $runtime (ok for pre-family runtimes)"
}
}
#G-128 follow-through: a fetched -r<N> artifact is not what bakes
#wrap - mapvfs and generated projects reference the WORKING name,
#which only 'use' materializes. One line while that gap exists.
$fm = [regex]::Match($runtime, '^(.*)-r([0-9]+)(\.[Ee][Xx][Ee])?$')
if ($fm.Success) {
$fetchedworking = $fm.Groups[1].Value + $fm.Groups[3].Value
if (-not (Test-Path -Path (Join-Path -Path $archfolder -ChildPath $fetchedworking) -PathType Leaf)) {
Write-Host "note: bakes and projects reference $fetchedworking - materialize it with: punk-runtime use $runtime"
}
}
#first fetch establishes the active runtime; later fetches never steal it
if ((Get-PunkActiveRuntime $archfolder) -eq "") {
Set-PunkActiveRuntime $archfolder $runtime

28
src/tests/shell/testsuites/binscripts/runtimecmd_freshness.test

@ -434,6 +434,34 @@ namespace eval ::testspace {
}\
-result [list 0 1 1 1 1 0 1]
#added 2026-07-29 (agent, G-128) - fetch of an -r<N> artifact whose WORKING name
#is absent prints the one-line materialization hint (fetch downloads immutable
#artifacts; only 'use' binds the mapvfs-referenced working name); the hint
#disappears once the working copy exists. Presence pinned on both payloads; the
#absence-after-use case via the cmd route only (same guard in both payloads -
#invocation economy).
test runtimecmd_fetch_materialize_hint {fetch without a working copy hints the use step; silent once materialized}\
-constraints $C -setup {
reset_stage
} -body {
set results {}
set hintpat "*note: bakes and projects reference fakert-alpha.exe - materialize it with: punk-runtime use fakert-alpha-r1.exe*"
set rp [run_cmdroute fetch fakert-alpha-r1.exe -platform testplat-x86_64]
lappend results cmd_exit [dict get $rp exit]
lappend results cmd_hint [string match $hintpat [dict get $rp output]]
set ru [run_cmdroute use fakert-alpha-r1.exe -platform testplat-x86_64]
lappend results use_exit [dict get $ru exit]
set rp2 [run_cmdroute fetch fakert-alpha-r1.exe -platform testplat-x86_64]
lappend results cmd_hint_after [string match $hintpat [dict get $rp2 output]]
reset_stage
set rb [run_bashroute fetch fakert-alpha-r1.exe -platform testplat-x86_64]
lappend results bash_exit [dict get $rb exit]
lappend results bash_hint [string match $hintpat [dict get $rb output]]
set results
} -cleanup {
reset_stage
} -result {cmd_exit 0 cmd_hint 1 use_exit 0 cmd_hint_after 0 bash_exit 0 bash_hint 1}
test runtimecmd_freshness_bash_series_mismatch_and_fetch_behind {bash payload extras: different-series actives get an incomparable verdict, and a diverging no-name fetch prints the BEHIND note with an inline activation hint}\
-constraints $C\
-setup {

Loading…
Cancel
Save