diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9c0b7a2..25708bbf 100644
--- a/CHANGELOG.md
+++ b/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`
"Project Versioning" section for the bump policy.
+## [0.18.0] - 2026-07-22
+
+- Canonical punkshell platform names (platform-folder synchronization survey; G-105 groundwork). New module `punk::platform` 0.1.0: `platforms` (canonical records with status supported/dormant/recognized and artifact-tree tiers), `normalize` (folds Tcl platform-package version-dependent aliases: amd64->x86_64, aarch64->arm64, macos->macosx, macosx arm->arm64), `local ?-tier lib|runtime?` (runtime tier collapses macOS per-arch to the universal `macosx` runtime-store name). New `help platforms` shell topic (punk 0.2.7) renders the canon with the running interpreter marked and the raw platform-package identifiers for comparison. Boot machinery (punkboot platform_generic snips in punk_main.tcl/project_main.tcl/make.tcl) now normalizes via an inline copy of the same mapping (platform_punk). `src/vendorlib_tcl8`/`_tcl9` platform subfolders synchronized to the canon: freebsd-amd64 renamed freebsd-x86_64, new freebsd-arm64/linux-arm64/macosx-arm64 (+ tracked linux-arm), msys-x86_64 marked dormant pending a utility decision. punk-runtime bash platform prongs emit canonical names (aarch64->linux-arm64 with no fetch default yet, arch-aware freebsd/openbsd/netbsd/dragonflybsd).
+
## [0.17.9] - 2026-07-22
- `bin/punk-runtime.cmd` (G-103/G-105 groundwork): cross-platform staging surface - `fetch`/`list`/`use` accept `-platform
` (punkbin platform-dir names; default = local platform, overridable via `PUNK_RUNTIME_PLATFORM` env) for listing/fetching/selecting runtimes of OTHER platforms (cross-build staging and guest provisioning); foreign fetches require an explicit runtime name; `list` flags runtimes whose metadata `target` disagrees with their folder (`!TARGET-MISMATCH`); `run` stays local-only (rejects `-platform`, ignores the env override). New `help` action (full operator reference: actions, options, env vars, examples) and a proper usage block on no-args invocation. Bash payload's FreeBSD platform dir aligned to punkbin's actual `freebsd-x86_64` (was `freebsd-amd64`). Layout-shipped copy refreshed.
diff --git a/bin/AGENTS.md b/bin/AGENTS.md
index 2040e746..da28d3c0 100644
--- a/bin/AGENTS.md
+++ b/bin/AGENTS.md
@@ -113,9 +113,11 @@ whose metadata `target` disagrees with the folder it sits in (`!TARGET-MISMATCH`
`run` is LOCAL ONLY - it rejects a leading `-platform` and ignores the env override
(later `run` args pass through to the runtime untouched). A no-args invocation prints
a short usage block; the `help` action gives the full operator reference (actions,
-options, env vars incl `PUNKBIN_URL`, examples). The bash payload's FreeBSD platform
-dir was aligned to punkbin's actual folder name (`freebsd-x86_64`; previously
-`freebsd-amd64`).
+options, env vars incl `PUNKBIN_URL`, examples). Platform names follow the CANONICAL
+punkshell platform-dir names defined by the `punk::platform` module and surfaced as
+`help platforms` in the punk shell (cpu tokens normalized: amd64->x86_64,
+aarch64->arm64; the bash payload's local-platform prongs emit canonical names - the
+FreeBSD dir was realigned from `freebsd-amd64` to `freebsd-x86_64` accordingly).
### Interactive verification shells
diff --git a/bin/punk-runtime.cmd b/bin/punk-runtime.cmd
index 88b619ed..ed9541f1 100755
--- a/bin/punk-runtime.cmd
+++ b/bin/punk-runtime.cmd
@@ -1299,41 +1299,54 @@ arch=$(uname -m) #machine/architecture
plat=$(uname -s) #platform/system
#even though most of the platform prongs are very similar,
#we keep the code separate so it can be tweaked easily for unexpected differences
-#each prong sets local_platform (the punkbin/bin-runtime platform-DIR name) and,
-#where a runtime is published for the platform, rt_default (default runtime name).
+#each prong sets local_platform (the CANONICAL punkshell platform-DIR name - see
+#punk::platform / 'help platforms': cpu tokens normalized amd64->x86_64,
+#aarch64->arm64) and, where a runtime is published for the platform, rt_default
+#(default runtime name).
+narch="$arch"
+case "$narch" in
+ amd64) narch="x86_64";;
+ aarch64|arm64) narch="arm64";;
+esac
if [[ "$plat" = "Linux"* ]]; then
if [[ "$arch" = "x86_64"* ]]; then
local_platform="linux-x86_64"
rt_default="tclkit-902-Linux64-intel-dyn"
runtime_available=1
+ elif [[ "$narch" = "arm64" ]]; then
+ #canonical arm64 (aarch64). punkbin's existing arm kit predates the
+ #arm64 name and sits in linux-arm - no fetch default here until a
+ #linux-arm64 punkbin folder exists; name runtimes explicitly.
+ local_platform="linux-arm64"
elif [[ "$arch" = "arm"* ]]; then
+ #32-bit arm
local_platform="linux-arm"
rt_default="tclkit-902-Linux64-arm-dyn"
runtime_available=1
else
- local_platform="linux-$arch"
+ local_platform="linux-$narch"
fi
os="linux"
elif [[ "$plat" = "Darwin"* ]]; then
os="macosx"
- #assumed to be Mach-O 'universal binaries' for both x86-64 and arm? - REVIEW
+ #universal (multi-arch) binaries - the runtime tier keeps ONE macosx folder
+ #(per-arch macosx-x86_64/macosx-arm64 names serve the lib tree tier)
local_platform="macosx"
rt_default="tclkit-902-Darwin64-dyn"
runtime_available=1
elif [[ "$plat" = "FreeBSD"* ]]; then
- #aligned 2026-07-22 to the punkbin repo's actual folder name (freebsd-x86_64;
- #this payload previously said freebsd-amd64 - the G-105 platform-dir naming
- #alignment item)
- local_platform="freebsd-x86_64"
+ #canonical names (2026-07-22): freebsd-x86_64 (punkbin's actual folder; this
+ #payload previously said freebsd-amd64) / freebsd-arm64
+ local_platform="freebsd-$narch"
os="freebsd"
elif [[ "$plat" == "DragonFly"* ]]; then
- local_platform="dragonflybsd-$arch"
+ local_platform="dragonflybsd-$narch"
os="dragonflybsd"
elif [[ "$plat" == "NetBSD"* ]]; then
- local_platform="netbsd-$arch"
+ local_platform="netbsd-$narch"
os="netbsd"
elif [[ "$plat" == "OpenBSD"* ]]; then
- local_platform="openbsd-amd64"
+ local_platform="openbsd-$narch"
os="openbsd"
elif [[ "$plat" == "MINGW32"* ]]; then
#REVIEW
diff --git a/goals/G-105-buildsuite-cross-target.md b/goals/G-105-buildsuite-cross-target.md
index 30078364..a6ef2472 100644
--- a/goals/G-105-buildsuite-cross-target.md
+++ b/goals/G-105-buildsuite-cross-target.md
@@ -73,3 +73,32 @@ dimension), G-102 (achieved 2026-07-21 - driver shape settled; target becomes a
Still open for this goal's alignment item: the zig-triple <-> platform-dir
mapping itself, openbsd-amd64 (payload) vs the x86_64 convention, and a
windows-arm default for the ps1 payload once punkbin carries such a folder.
+- 2026-07-22 CANONICAL PLATFORM NAMES SETTLED (user-directed survey of punkbin vs
+ punkshell platform folders; resolves this goal's "platform-dir naming alignment"
+ item on the punkshell side - the zig-triple <-> platform-dir mapping remains this
+ goal's build-time work). Canon = punk::platform module (src/modules/punk/
+ platform-999999.0a1.0.tm; 'help platforms' topic): - punkshell
+ platform-dir names with cpu normalized amd64->x86_64, aarch64->arm64 (arm =
+ 32-bit; on macosx arm folds to arm64), os macos->macosx; special universal
+ 'macosx' for the runtime tier (punkbin + bin/runtime keep ONE macOS folder -
+ make.tcl convention blessed), per-arch macosx-x86_64/macosx-arm64 for lib trees.
+ Supported: win32-x86_64, linux-x86_64, linux-arm64, linux-arm, macosx,
+ macosx-x86_64, macosx-arm64, freebsd-x86_64, freebsd-arm64. Dormant:
+ msys-x86_64 (utility under user review). Recognized (no artifacts):
+ openbsd/netbsd/dragonflybsd-x86_64. Tcl's platform package stays the RAW
+ identifier (version-varying outputs: 1.1.x renamed macos, aarch64 passthrough);
+ punk::platform::normalize is the folding layer; the punkboot platform_generic
+ snips (punk_main/project_main/make.tcl) gained an inline platform_punk
+ normalization (kept in sync by comment contract). vendorlib_tcl8/9 platform
+ subfolders synchronized to canon (freebsd-amd64 -> freebsd-x86_64 rename;
+ freebsd-arm64/linux-arm64/macosx-arm64 added; stray untracked macosx-arm
+ empties removed). punk-runtime prongs emit canon (linux-arm64 has NO fetch
+ default until punkbin carries that folder). FLAGGED for user decisions:
+ (a) punkbin linux-arm holds tclkit-902-Linux64-arm-dyn which by its name is an
+ arm64 build - recommend a linux-arm64 punkbin folder at next arm publish
+ (artifacts immutable, no moves); (b) msys-x86_64 disposition; (c) vendored
+ platform-1.0.19 vs core 1.1.x re-vendor (normalization makes punkshell robust
+ either way - upgrade optional); (d) src/vfs stays UNcategorized by platform
+ (mapvfs mappings + purpose-names carry the platform axis) - acceptable now;
+ recommend revisiting when G-105 cross-wraps land (a mapvfs platform column per
+ make.tcl's existing x-platform TODO beats restructuring the .vfs tree).
diff --git a/punkproject.toml b/punkproject.toml
index 9aa8b82f..64253049 100644
--- a/punkproject.toml
+++ b/punkproject.toml
@@ -1,4 +1,4 @@
[project]
name = "punkshell"
-version = "0.17.9"
+version = "0.18.0"
license = "BSD-2-Clause"
diff --git a/src/make.tcl b/src/make.tcl
index fd4bf051..36c83222 100644
--- a/src/make.tcl
+++ b/src/make.tcl
@@ -278,6 +278,23 @@ namespace eval ::punkboot::lib {
return "${plat}-${cpu}"
}
+ proc platform_punk {} {
+ #canonical punkshell platform-dir name: platform_generic normalized.
+ #INLINE COPY of punk::platform::normalize (src/modules/punk/platform-*.tm;
+ #'help platforms' documents the canon) - the boot stage cannot package
+ #require, so keep this mapping in sync with that module:
+ #amd64->x86_64, aarch64->arm64, macos->macosx, macosx arm->arm64.
+ set parts [split [platform_generic] -]
+ set cpu [lindex $parts end]
+ set os [join [lrange $parts 0 end-1] -]
+ if {$os eq "macos"} {set os macosx}
+ switch -- $cpu {
+ amd64 {set cpu x86_64}
+ aarch64 {set cpu arm64}
+ arm {if {$os eq "macosx"} {set cpu arm64}}
+ }
+ return "${os}-${cpu}"
+ }
}
@@ -370,7 +387,7 @@ set startdir [pwd]
# -------------------------------------------------------------------------------------
set bootsupport_module_paths [list]
set bootsupport_library_paths [list]
-set this_platform_generic [punkboot::lib::platform_generic]
+set this_platform_generic [punkboot::lib::platform_punk] ;#normalized punkshell platform-dir name (punk::platform canon)
#we always create these lists in order of desired precedence.
# - this is the same order when adding to auto_path - but will need to be reversed when using tcl:tm::add
if {[file exists [file join $::punkboot::scriptfolder bootsupport]]} {
diff --git a/src/modules/punk-999999.0a1.0.tm b/src/modules/punk-999999.0a1.0.tm
index 6c164100..e5de89ff 100644
--- a/src/modules/punk-999999.0a1.0.tm
+++ b/src/modules/punk-999999.0a1.0.tm
@@ -8983,10 +8983,71 @@ namespace eval punk {
return $chunks
}
- register topics {help} "List help topics"
- register tcl {} "Tcl version warnings"
- register env {environment} "punkshell environment vars"
- register console {term terminal} "Some console behaviour tests and warnings"
+ punk::args::define {
+ @id -id ::punk::helptopic::platforms
+ @cmd -name "help platforms"\
+ -summary\
+ "Canonical punkshell platform names."\
+ -help\
+ "Show the canonical punkshell platform-dir names
+ (punk::platform::platforms) with status and the artifact-tree
+ tiers each name serves, marking the running interpreter's own
+ platform. These names organize the punkbin artifact repo's
+ platform folders, bin/runtime// (punk-runtime
+ fetch/list/use -platform), the lib_tclX / vendorlib_tclX
+ auto_path dirs wired by the boot, and the runtime-artifact
+ metadata target field. The raw Tcl platform-package identifiers
+ are shown for comparison (punk::platform::normalize folds their
+ version-dependent aliases - amd64/aarch64/macos - into the
+ canonical names)."
+ @values -min 0 -max 0
+ }
+ proc platforms {context args} {
+ if {[catch {package require punk::platform} errM]} {
+ return [list [list stderr "help platforms: punk::platform package not available ($errM)\n"]]
+ }
+ set frametype [dict get $context frametype]
+ set chunks [list]
+ set local_lib [punk::platform::local -tier lib]
+ set local_runtime [punk::platform::local -tier runtime]
+ set title "[a+ brightgreen] Canonical punkshell platform names: "
+ set t [textblock::class::table new -show_seps 0]
+ $t configure -frametype $frametype
+ $t add_column -headers [list "Platform"]
+ $t add_column -headers [list "Status"]
+ $t add_column -headers [list "Tiers"]
+ $t add_column -headers [list "Notes"]
+ dict for {p pinfo} [punk::platform::platforms] {
+ set pshown $p
+ if {$p eq $local_lib || $p eq $local_runtime} {
+ set pshown "* $p"
+ }
+ $t add_row [list $pshown [dict get $pinfo status] [join [dict get $pinfo tiers] ,] [dict get $pinfo notes]]
+ }
+ foreach c {0 1 2} {
+ $t configure_column $c -minwidth [expr {[$t column_datawidth $c] + 2}]
+ }
+ $t configure -title $title
+ set text [$t print]
+ $t destroy
+ lappend chunks [list stdout $text]
+ set detail "* = this interpreter. local: lib-tier $local_lib"
+ if {$local_runtime ne $local_lib} {
+ append detail " runtime-tier $local_runtime"
+ }
+ append detail "\ntiers: runtime = punkbin + bin/runtime folders; lib = lib_tclX/vendorlib_tclX auto_path dirs"
+ catch {
+ append detail "\nraw Tcl platform package ([package present platform]): generic [platform::generic] identify [platform::identify]"
+ }
+ lappend chunks [list stdout $detail\n]
+ return $chunks
+ }
+
+ register topics {help} "List help topics"
+ register tcl {} "Tcl version warnings"
+ register env {environment} "punkshell environment vars"
+ register console {term terminal} "Some console behaviour tests and warnings"
+ register platforms {platform} "Canonical punkshell platform names"
}
#return list of {chan chunk} elements
diff --git a/src/modules/punk-buildversion.txt b/src/modules/punk-buildversion.txt
index 1f4249c1..3fcf3368 100644
--- a/src/modules/punk-buildversion.txt
+++ b/src/modules/punk-buildversion.txt
@@ -1,6 +1,7 @@
-0.2.6
+0.2.7
#First line must be a semantic version number
#all other lines are ignored.
+#0.2.7 - new 'help platforms' topic (aliases: platform): canonical punkshell platform-dir names from punk::platform::platforms rendered with status/tiers/notes, the running interpreter's lib-tier and runtime-tier names marked, and the raw Tcl platform-package identifiers (generic/identify) shown for comparison. Degrades cleanly when punk::platform is unavailable. All platform/platforms prefixes are mutually ambiguous so they fall through to command lookup (env/environment precedent).
#0.2.6 - G-076: 'help tcl' renders the mitigated/mitigation buginfo axis (punk::lib 0.4.3+): a triggered check reporting mitigated keeps its severity level but displays 'warning level: (mitigated)' in subdued grey (term-grey foreground) instead of the level colour, followed by an indented 'mitigated: ' block when mitigation text is supplied. Unmitigated warnings render unchanged.
#0.2.5 - G-045: ::punk::helptopic::define_docs converts from interim left-margin authoring to indented block-form values under the new punk::args @normalize directive (the constructed-definition normalization consumer proof): basehelp/topichelp/help_chunks-extra are braced indented blocks with a structural leading newline, the generated definitions declare @normalize, and the -unindentedfields declarations from punk 0.2.4 are dropped. Rendered 'i help'/'i help_chunks' output unchanged (verified aligned incl. the blank-line separator in help_chunks).
#0.2.4 - G-045: 'i help' usage table alignment - ::punk::helptopic::define_docs authors its help text at the left margin and declares -unindentedfields {-help} on both the generated @cmd line (honoured as of punk::args 0.6.1) and the topic argument line. Previously the @cmd -help braced literal carried ~16 spaces of source indent into the constructed definition (no whole-block normalization), rendering Description continuations +12 right of the first line, and the \n-relative topic -help rendered its first line +4 (the injected display prefix). Both blocks now render flush. Text content unchanged (manual ~70-col folding retained).
diff --git a/src/modules/punk/platform-999999.0a1.0.tm b/src/modules/punk/platform-999999.0a1.0.tm
new file mode 100644
index 00000000..a4de7182
--- /dev/null
+++ b/src/modules/punk/platform-999999.0a1.0.tm
@@ -0,0 +1,219 @@
+# -*- tcl -*-
+# Maintenance Instruction: leave the 999999.xxx.x as is and use 'pmix make' or src/make.tcl to update from -buildversion.txt
+#
+# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem.
+# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository.
+# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
+# (C) 2026
+#
+# @@ Meta Begin
+# Application punk::platform 999999.0a1.0
+# Meta platform tcl
+# Meta license BSD
+# @@ Meta End
+
+
+# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
+## Requirements
+package require platform ;#Tcl's own platform package (vendored 1.0.19 in kits; 1.1.x in tcl9 core) - the RAW identifier underneath this module's normalization
+
+
+# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
+namespace eval punk::platform {
+ #punk::platform - the CANONICAL punkshell platform naming layer (2026-07-22
+ #platform-folder synchronization; groundwork for the G-105 cross-target arc).
+ #
+ #punkshell artifact trees are organized by PLATFORM-DIR names of the form
+ #- (e.g win32-x86_64), used by: the punkbin artifact repo's top-level
+ #folders, bin/runtime// (the runtime store punk-runtime manages),
+ #lib_tclX/ + vendorlib_tclX/ auto_path dirs (wired by the
+ #boot machinery), and the G-103 runtime artifact metadata 'target' field.
+ #
+ #Tcl's platform package remains the raw identifier (platform::generic /
+ #platform::identify) but its outputs vary by version and pass some machine
+ #names through unmapped - the differences this module's normalize absorbs:
+ # - cpu 'amd64' (BSD machine names) -> x86_64
+ # - cpu 'aarch64' (linux arm64) -> arm64
+ # - os 'macos' (platform 1.1.x on osVersion>19; older versions and the
+ # boot's snipped copy say 'macosx') -> macosx
+ # - macosx cpu 'arm' -> arm64 (platform::generic's 'arm*' glob collapses
+ # the darwin 'arm64' machine name to 'arm'; Apple silicon is 64-bit only,
+ # so the arm token on macosx always means arm64. Elsewhere 'arm' is a
+ # genuine 32-bit token and is preserved.)
+ #The special name 'macosx' (no cpu suffix) is the RUNTIME-tier convention for
+ #universal (multi-arch) macOS binaries - punkbin and bin/runtime keep one
+ #universal folder; the per-arch macosx-x86_64/macosx-arm64 names serve the
+ #lib-tree tier where per-arch payloads are the norm.
+ #
+ #The boot machinery (punkboot::lib in src/vfs/_config/punk_main.tcl /
+ #project_main.tcl and src/make.tcl) cannot 'package require' at its stage and
+ #carries a snipped platform::generic plus an inline copy of THIS module's
+ #normalization mapping - if the mapping here changes, those copies must
+ #change with it (each carries a pointer comment to this module).
+
+ namespace eval argdoc {
+ variable PUNKARGS
+ }
+
+ #canonical platform records. status:
+ # supported - a punkshell target: artifact trees exist or are planned and
+ # tooling/build arcs (G-103/G-105) treat it as a real target
+ # dormant - recognized and folders may exist, but utility is under review
+ # recognized - a name the naming scheme reserves; no artifacts or tooling yet
+ #tiers: which artifact-tree tiers use the name -
+ # runtime = punkbin platform folders + bin/runtime//
+ # lib = lib_tclX/ + vendorlib_tclX/ auto_path dirs
+ variable platforms {
+ win32-x86_64 {status supported tiers {runtime lib} notes "primary development platform"}
+ linux-x86_64 {status supported tiers {runtime lib} notes ""}
+ linux-arm64 {status supported tiers {runtime lib} notes "aarch64; punkbin's existing arm kit predates the arm64 name and sits in linux-arm"}
+ linux-arm {status supported tiers {runtime lib} notes "32-bit arm"}
+ macosx {status supported tiers {runtime} notes "universal (multi-arch) macOS binaries - runtime tier keeps one folder"}
+ macosx-x86_64 {status supported tiers {lib} notes ""}
+ macosx-arm64 {status supported tiers {lib} notes "Apple silicon"}
+ freebsd-x86_64 {status supported tiers {runtime lib} notes ""}
+ freebsd-arm64 {status supported tiers {runtime lib} notes "no artifacts yet"}
+ msys-x86_64 {status dormant tiers {lib} notes "msys/cygwin-built tclsh runtimes; utility under review"}
+ openbsd-x86_64 {status recognized tiers {} notes ""}
+ netbsd-x86_64 {status recognized tiers {} notes ""}
+ dragonflybsd-x86_64 {status recognized tiers {} notes ""}
+ }
+
+ namespace eval argdoc {
+ variable PUNKARGS
+ lappend PUNKARGS [list {
+ @id -id ::punk::platform::platforms
+ @cmd -name punk::platform::platforms\
+ -summary\
+ "Canonical punkshell platform records."\
+ -help\
+ "Return the canonical punkshell platform-name records as a dict
+ keyed by platform-dir name (e.g win32-x86_64). Each value is a
+ dict with keys:
+ status supported|dormant|recognized
+ tiers which artifact-tree tiers use the name
+ (runtime = punkbin + bin/runtime folders,
+ lib = lib_tclX/vendorlib_tclX auto_path dirs)
+ notes free-text qualifiers
+ These names are the contract for punkbin platform folders,
+ bin/runtime//, lib_tclX/vendorlib_tclX platform
+ dirs and the G-103 runtime-artifact metadata target field.
+ See also 'help platforms' in the punk shell."
+ @values -min 0 -max 0
+ }]
+ }
+ proc platforms {} {
+ variable platforms
+ return $platforms
+ }
+
+ namespace eval argdoc {
+ variable PUNKARGS
+ lappend PUNKARGS [list {
+ @id -id ::punk::platform::normalize
+ @cmd -name punk::platform::normalize\
+ -summary\
+ "Normalize a platform identifier to the canonical punkshell name."\
+ -help\
+ "Normalize a platform::generic-style - identifier (or an
+ already-canonical punkshell name) to the canonical punkshell
+ platform-dir name:
+ cpu amd64 -> x86_64, aarch64 -> arm64
+ os macos -> macosx (Tcl platform 1.1.x renamed modern macOS)
+ macosx cpu arm -> arm64 (platform::generic's arm* glob folds
+ the darwin arm64 machine name to arm; Apple silicon is
+ 64-bit only - non-macosx 'arm' stays 32-bit arm)
+ Unrecognized os/cpu tokens pass through unchanged - normalize
+ never invents names, it only folds known aliases."
+ @values -min 1 -max 1
+ platform -type string -help\
+ "Platform identifier, e.g the result of platform::generic."
+ }]
+ }
+ proc normalize {platform} {
+ set parts [split $platform -]
+ if {[llength $parts] < 2} {
+ #single-token names (e.g the universal 'macosx') - fold macos only
+ if {$platform eq "macos"} {
+ return macosx
+ }
+ return $platform
+ }
+ #os may itself contain a dash in principle - treat last token as cpu
+ set cpu [lindex $parts end]
+ set os [join [lrange $parts 0 end-1] -]
+ switch -- $os {
+ macos {set os macosx}
+ }
+ switch -- $cpu {
+ amd64 {set cpu x86_64}
+ aarch64 {set cpu arm64}
+ arm {
+ if {$os eq "macosx"} {
+ set cpu arm64
+ }
+ }
+ }
+ return "${os}-${cpu}"
+ }
+
+ namespace eval argdoc {
+ variable PUNKARGS
+ lappend PUNKARGS [list {
+ @id -id ::punk::platform::local
+ @cmd -name punk::platform::local\
+ -summary\
+ "Canonical punkshell platform name of the running interpreter."\
+ -help\
+ "Return the canonical punkshell platform-dir name for the running
+ interpreter: platform::generic normalized per
+ punk::platform::normalize.
+ With -tier runtime, macosx per-arch names collapse to the
+ universal 'macosx' (the runtime-store convention: punkbin and
+ bin/runtime keep one universal macOS folder; the same collapse
+ src/make.tcl applies when locating bin/runtime/).
+ -tier lib (the default) returns the per-arch name used by the
+ lib_tclX/vendorlib_tclX auto_path dirs."
+ @opts
+ -tier -type string -default lib -choices {lib runtime} -help\
+ "Artifact-tree tier the name is for."
+ @values -min 0 -max 0
+ }]
+ }
+ proc local {args} {
+ set tier lib
+ foreach {k v} $args {
+ switch -- $k {
+ -tier {
+ if {$v ni {lib runtime}} {
+ error "punk::platform::local - invalid -tier '$v' (expected lib|runtime)"
+ }
+ set tier $v
+ }
+ default {
+ error "punk::platform::local - unknown option '$k' (known: -tier)"
+ }
+ }
+ }
+ set p [normalize [::platform::generic]]
+ if {$tier eq "runtime" && [string match macosx-* $p]} {
+ return macosx
+ }
+ return $p
+ }
+}
+
+
+namespace eval ::punk::args::register {
+ #use fully qualified so 8.6 doesn't find existing var in global namespace
+ lappend ::punk::args::register::NAMESPACES ::punk::platform
+}
+
+
+# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
+## Ready
+package provide punk::platform [namespace eval punk::platform {
+ variable version
+ set version 999999.0a1.0
+}]
+return
diff --git a/src/modules/punk/platform-buildversion.txt b/src/modules/punk/platform-buildversion.txt
new file mode 100644
index 00000000..4abe8a12
--- /dev/null
+++ b/src/modules/punk/platform-buildversion.txt
@@ -0,0 +1,4 @@
+0.1.0
+#First line must be a semantic version number
+#all other lines are ignored.
+#0.1.0 - initial release (2026-07-22 platform-folder synchronization; G-105 groundwork): the canonical punkshell platform naming layer over Tcl's platform package - platforms (canonical records: status/tiers/notes), normalize (amd64->x86_64, aarch64->arm64, macos->macosx, macosx arm->arm64), local ?-tier lib|runtime? (runtime tier collapses macosx per-arch to the universal macosx runtime-store name). Canon consumed by: punkbin platform folders, bin/runtime//, lib_tclX/vendorlib_tclX platform dirs, G-103 artifact metadata targets, 'help platforms' topic. The boot machinery (punkboot::lib platform_generic snips in punk_main.tcl/project_main.tcl/make.tcl) carries an inline copy of the normalization mapping - keep in sync.
diff --git a/src/project_layouts/vendor/punk/project-0.1/bin/punk-runtime.cmd b/src/project_layouts/vendor/punk/project-0.1/bin/punk-runtime.cmd
index 88b619ed..ed9541f1 100644
--- a/src/project_layouts/vendor/punk/project-0.1/bin/punk-runtime.cmd
+++ b/src/project_layouts/vendor/punk/project-0.1/bin/punk-runtime.cmd
@@ -1299,41 +1299,54 @@ arch=$(uname -m) #machine/architecture
plat=$(uname -s) #platform/system
#even though most of the platform prongs are very similar,
#we keep the code separate so it can be tweaked easily for unexpected differences
-#each prong sets local_platform (the punkbin/bin-runtime platform-DIR name) and,
-#where a runtime is published for the platform, rt_default (default runtime name).
+#each prong sets local_platform (the CANONICAL punkshell platform-DIR name - see
+#punk::platform / 'help platforms': cpu tokens normalized amd64->x86_64,
+#aarch64->arm64) and, where a runtime is published for the platform, rt_default
+#(default runtime name).
+narch="$arch"
+case "$narch" in
+ amd64) narch="x86_64";;
+ aarch64|arm64) narch="arm64";;
+esac
if [[ "$plat" = "Linux"* ]]; then
if [[ "$arch" = "x86_64"* ]]; then
local_platform="linux-x86_64"
rt_default="tclkit-902-Linux64-intel-dyn"
runtime_available=1
+ elif [[ "$narch" = "arm64" ]]; then
+ #canonical arm64 (aarch64). punkbin's existing arm kit predates the
+ #arm64 name and sits in linux-arm - no fetch default here until a
+ #linux-arm64 punkbin folder exists; name runtimes explicitly.
+ local_platform="linux-arm64"
elif [[ "$arch" = "arm"* ]]; then
+ #32-bit arm
local_platform="linux-arm"
rt_default="tclkit-902-Linux64-arm-dyn"
runtime_available=1
else
- local_platform="linux-$arch"
+ local_platform="linux-$narch"
fi
os="linux"
elif [[ "$plat" = "Darwin"* ]]; then
os="macosx"
- #assumed to be Mach-O 'universal binaries' for both x86-64 and arm? - REVIEW
+ #universal (multi-arch) binaries - the runtime tier keeps ONE macosx folder
+ #(per-arch macosx-x86_64/macosx-arm64 names serve the lib tree tier)
local_platform="macosx"
rt_default="tclkit-902-Darwin64-dyn"
runtime_available=1
elif [[ "$plat" = "FreeBSD"* ]]; then
- #aligned 2026-07-22 to the punkbin repo's actual folder name (freebsd-x86_64;
- #this payload previously said freebsd-amd64 - the G-105 platform-dir naming
- #alignment item)
- local_platform="freebsd-x86_64"
+ #canonical names (2026-07-22): freebsd-x86_64 (punkbin's actual folder; this
+ #payload previously said freebsd-amd64) / freebsd-arm64
+ local_platform="freebsd-$narch"
os="freebsd"
elif [[ "$plat" == "DragonFly"* ]]; then
- local_platform="dragonflybsd-$arch"
+ local_platform="dragonflybsd-$narch"
os="dragonflybsd"
elif [[ "$plat" == "NetBSD"* ]]; then
- local_platform="netbsd-$arch"
+ local_platform="netbsd-$narch"
os="netbsd"
elif [[ "$plat" == "OpenBSD"* ]]; then
- local_platform="openbsd-amd64"
+ local_platform="openbsd-$narch"
os="openbsd"
elif [[ "$plat" == "MINGW32"* ]]; then
#REVIEW
diff --git a/src/scriptapps/bin/punk-runtime.bash b/src/scriptapps/bin/punk-runtime.bash
index f10cbd20..44e0f7cd 100644
--- a/src/scriptapps/bin/punk-runtime.bash
+++ b/src/scriptapps/bin/punk-runtime.bash
@@ -19,41 +19,54 @@ arch=$(uname -m) #machine/architecture
plat=$(uname -s) #platform/system
#even though most of the platform prongs are very similar,
#we keep the code separate so it can be tweaked easily for unexpected differences
-#each prong sets local_platform (the punkbin/bin-runtime platform-DIR name) and,
-#where a runtime is published for the platform, rt_default (default runtime name).
+#each prong sets local_platform (the CANONICAL punkshell platform-DIR name - see
+#punk::platform / 'help platforms': cpu tokens normalized amd64->x86_64,
+#aarch64->arm64) and, where a runtime is published for the platform, rt_default
+#(default runtime name).
+narch="$arch"
+case "$narch" in
+ amd64) narch="x86_64";;
+ aarch64|arm64) narch="arm64";;
+esac
if [[ "$plat" = "Linux"* ]]; then
if [[ "$arch" = "x86_64"* ]]; then
local_platform="linux-x86_64"
rt_default="tclkit-902-Linux64-intel-dyn"
runtime_available=1
+ elif [[ "$narch" = "arm64" ]]; then
+ #canonical arm64 (aarch64). punkbin's existing arm kit predates the
+ #arm64 name and sits in linux-arm - no fetch default here until a
+ #linux-arm64 punkbin folder exists; name runtimes explicitly.
+ local_platform="linux-arm64"
elif [[ "$arch" = "arm"* ]]; then
+ #32-bit arm
local_platform="linux-arm"
rt_default="tclkit-902-Linux64-arm-dyn"
runtime_available=1
else
- local_platform="linux-$arch"
+ local_platform="linux-$narch"
fi
os="linux"
elif [[ "$plat" = "Darwin"* ]]; then
os="macosx"
- #assumed to be Mach-O 'universal binaries' for both x86-64 and arm? - REVIEW
+ #universal (multi-arch) binaries - the runtime tier keeps ONE macosx folder
+ #(per-arch macosx-x86_64/macosx-arm64 names serve the lib tree tier)
local_platform="macosx"
rt_default="tclkit-902-Darwin64-dyn"
runtime_available=1
elif [[ "$plat" = "FreeBSD"* ]]; then
- #aligned 2026-07-22 to the punkbin repo's actual folder name (freebsd-x86_64;
- #this payload previously said freebsd-amd64 - the G-105 platform-dir naming
- #alignment item)
- local_platform="freebsd-x86_64"
+ #canonical names (2026-07-22): freebsd-x86_64 (punkbin's actual folder; this
+ #payload previously said freebsd-amd64) / freebsd-arm64
+ local_platform="freebsd-$narch"
os="freebsd"
elif [[ "$plat" == "DragonFly"* ]]; then
- local_platform="dragonflybsd-$arch"
+ local_platform="dragonflybsd-$narch"
os="dragonflybsd"
elif [[ "$plat" == "NetBSD"* ]]; then
- local_platform="netbsd-$arch"
+ local_platform="netbsd-$narch"
os="netbsd"
elif [[ "$plat" == "OpenBSD"* ]]; then
- local_platform="openbsd-amd64"
+ local_platform="openbsd-$narch"
os="openbsd"
elif [[ "$plat" == "MINGW32"* ]]; then
#REVIEW
diff --git a/src/vendorlib_tcl8/README.md b/src/vendorlib_tcl8/README.md
index 5a80a367..cb643855 100644
--- a/src/vendorlib_tcl8/README.md
+++ b/src/vendorlib_tcl8/README.md
@@ -6,3 +6,11 @@ These should generally be kept to a minimum
- todo: dependency and version number tracking; along with the provision of a mechanism for the project end-users to update.
+
+Platform subfolder structure (2026-07-22): the platform-named subfolders
+follow the CANONICAL punkshell platform-dir names defined by the
+punk::platform module (also surfaced as 'help platforms' in the punk shell)
+plus the special 'allplatforms' folder for platform-independent libraries.
+The boot machinery adds allplatforms plus the running platform's folder to
+auto_path. Keep the set of subfolders here in sync with punk::platform's
+supported/dormant records across BOTH vendorlib_tcl8 and vendorlib_tcl9.
diff --git a/src/vendorlib_tcl8/freebsd-amd64/README.md b/src/vendorlib_tcl8/freebsd-amd64/README.md
deleted file mode 100644
index 944bd520..00000000
--- a/src/vendorlib_tcl8/freebsd-amd64/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Tcl library dependencies
-
-pkgIndex.tcl based libraries specific to the freebsd-amd64 platform.
-Note that amd64 is equivalent to x86_64 in this context.
-
-
-
-
-
diff --git a/src/vendorlib_tcl8/freebsd-arm64/README.md b/src/vendorlib_tcl8/freebsd-arm64/README.md
new file mode 100644
index 00000000..fe498974
--- /dev/null
+++ b/src/vendorlib_tcl8/freebsd-arm64/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the freebsd-arm64 platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl8/freebsd-x86_64/README.md b/src/vendorlib_tcl8/freebsd-x86_64/README.md
new file mode 100644
index 00000000..ae189f9c
--- /dev/null
+++ b/src/vendorlib_tcl8/freebsd-x86_64/README.md
@@ -0,0 +1,5 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the freebsd-x86_64 platform.
+(Renamed from freebsd-amd64 2026-07-22: punkshell canonical platform names
+normalize amd64 to x86_64 - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl8/linux-arm/README.md b/src/vendorlib_tcl8/linux-arm/README.md
new file mode 100644
index 00000000..5c81bf27
--- /dev/null
+++ b/src/vendorlib_tcl8/linux-arm/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the linux-arm platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl8/linux-arm64/README.md b/src/vendorlib_tcl8/linux-arm64/README.md
new file mode 100644
index 00000000..688ad1b0
--- /dev/null
+++ b/src/vendorlib_tcl8/linux-arm64/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the linux-arm64 platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl8/macosx-arm64/README.md b/src/vendorlib_tcl8/macosx-arm64/README.md
new file mode 100644
index 00000000..ae6996f0
--- /dev/null
+++ b/src/vendorlib_tcl8/macosx-arm64/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the macosx-arm64 platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl8/msys-x86_64/README.md b/src/vendorlib_tcl8/msys-x86_64/README.md
index 71f7a7cd..3ed83bc4 100644
--- a/src/vendorlib_tcl8/msys-x86_64/README.md
+++ b/src/vendorlib_tcl8/msys-x86_64/README.md
@@ -1,8 +1,6 @@
Tcl library dependencies
-pkgIndex.tcl based libraries specific to the msys-x86_64 platform.
-This is a somewhat unix-like environment running on windows.
-
-
-
-
+pkgIndex.tcl based libraries specific to the msys-x86_64 platform
+(msys/cygwin-built tclsh runtimes).
+Status: DORMANT - recognized canonical name but utility under review
+(2026-07-22 platform survey; see punk::platform / 'help platforms').
diff --git a/src/vendorlib_tcl9/README.md b/src/vendorlib_tcl9/README.md
index 5a80a367..cb643855 100644
--- a/src/vendorlib_tcl9/README.md
+++ b/src/vendorlib_tcl9/README.md
@@ -6,3 +6,11 @@ These should generally be kept to a minimum
- todo: dependency and version number tracking; along with the provision of a mechanism for the project end-users to update.
+
+Platform subfolder structure (2026-07-22): the platform-named subfolders
+follow the CANONICAL punkshell platform-dir names defined by the
+punk::platform module (also surfaced as 'help platforms' in the punk shell)
+plus the special 'allplatforms' folder for platform-independent libraries.
+The boot machinery adds allplatforms plus the running platform's folder to
+auto_path. Keep the set of subfolders here in sync with punk::platform's
+supported/dormant records across BOTH vendorlib_tcl8 and vendorlib_tcl9.
diff --git a/src/vendorlib_tcl9/freebsd-amd64/README.md b/src/vendorlib_tcl9/freebsd-amd64/README.md
deleted file mode 100644
index 944bd520..00000000
--- a/src/vendorlib_tcl9/freebsd-amd64/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Tcl library dependencies
-
-pkgIndex.tcl based libraries specific to the freebsd-amd64 platform.
-Note that amd64 is equivalent to x86_64 in this context.
-
-
-
-
-
diff --git a/src/vendorlib_tcl9/freebsd-arm64/README.md b/src/vendorlib_tcl9/freebsd-arm64/README.md
new file mode 100644
index 00000000..fe498974
--- /dev/null
+++ b/src/vendorlib_tcl9/freebsd-arm64/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the freebsd-arm64 platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl9/freebsd-x86_64/README.md b/src/vendorlib_tcl9/freebsd-x86_64/README.md
new file mode 100644
index 00000000..ae189f9c
--- /dev/null
+++ b/src/vendorlib_tcl9/freebsd-x86_64/README.md
@@ -0,0 +1,5 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the freebsd-x86_64 platform.
+(Renamed from freebsd-amd64 2026-07-22: punkshell canonical platform names
+normalize amd64 to x86_64 - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl9/linux-arm/README.md b/src/vendorlib_tcl9/linux-arm/README.md
new file mode 100644
index 00000000..5c81bf27
--- /dev/null
+++ b/src/vendorlib_tcl9/linux-arm/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the linux-arm platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl9/linux-arm64/README.md b/src/vendorlib_tcl9/linux-arm64/README.md
new file mode 100644
index 00000000..688ad1b0
--- /dev/null
+++ b/src/vendorlib_tcl9/linux-arm64/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the linux-arm64 platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl9/macosx-arm64/README.md b/src/vendorlib_tcl9/macosx-arm64/README.md
new file mode 100644
index 00000000..ae6996f0
--- /dev/null
+++ b/src/vendorlib_tcl9/macosx-arm64/README.md
@@ -0,0 +1,4 @@
+Tcl library dependencies
+
+pkgIndex.tcl based libraries specific to the macosx-arm64 platform.
+(Canonical punkshell platform name - see punk::platform / 'help platforms')
diff --git a/src/vendorlib_tcl9/msys-x86_64/README.md b/src/vendorlib_tcl9/msys-x86_64/README.md
index 71f7a7cd..3ed83bc4 100644
--- a/src/vendorlib_tcl9/msys-x86_64/README.md
+++ b/src/vendorlib_tcl9/msys-x86_64/README.md
@@ -1,8 +1,6 @@
Tcl library dependencies
-pkgIndex.tcl based libraries specific to the msys-x86_64 platform.
-This is a somewhat unix-like environment running on windows.
-
-
-
-
+pkgIndex.tcl based libraries specific to the msys-x86_64 platform
+(msys/cygwin-built tclsh runtimes).
+Status: DORMANT - recognized canonical name but utility under review
+(2026-07-22 platform survey; see punk::platform / 'help platforms').
diff --git a/src/vfs/_config/project_main.tcl b/src/vfs/_config/project_main.tcl
index 40446f82..46234ccb 100644
--- a/src/vfs/_config/project_main.tcl
+++ b/src/vfs/_config/project_main.tcl
@@ -124,6 +124,23 @@ apply { args {
return "${plat}-${cpu}"
}
+ proc platform_punk {} {
+ #canonical punkshell platform-dir name: platform_generic normalized.
+ #INLINE COPY of punk::platform::normalize (src/modules/punk/platform-*.tm;
+ #'help platforms' documents the canon) - the boot stage cannot package
+ #require, so keep this mapping in sync with that module:
+ #amd64->x86_64, aarch64->arm64, macos->macosx, macosx arm->arm64.
+ set parts [split [platform_generic] -]
+ set cpu [lindex $parts end]
+ set os [join [lrange $parts 0 end-1] -]
+ if {$os eq "macos"} {set os macosx}
+ switch -- $cpu {
+ amd64 {set cpu x86_64}
+ aarch64 {set cpu arm64}
+ arm {if {$os eq "macosx"} {set cpu arm64}}
+ }
+ return "${os}-${cpu}"
+ }
}
set has_zipfs [expr {[info commands tcl::zipfs::root] ne ""}]
@@ -609,7 +626,7 @@ apply { args {
#so we prepend to auto_path using a slightly inefficient method. Should be fine on relatively small list like this
#eventually it should just be something like 'ledit ::auto_path -1 -1 $libfolder'
if {"dev" in $package_modes} {
- set platform [::punkboot::platform_generic]
+ set platform [::punkboot::platform_punk]
#on windows - case differences dont matter - but can stop us finding path in auto_path
#on other platforms, case differences could represent different paths
#review
diff --git a/src/vfs/_config/punk_main.tcl b/src/vfs/_config/punk_main.tcl
index b3c4f232..b6d15893 100644
--- a/src/vfs/_config/punk_main.tcl
+++ b/src/vfs/_config/punk_main.tcl
@@ -219,6 +219,23 @@ apply { args {
return "${plat}-${cpu}"
}
+ proc platform_punk {} {
+ #canonical punkshell platform-dir name: platform_generic normalized.
+ #INLINE COPY of punk::platform::normalize (src/modules/punk/platform-*.tm;
+ #'help platforms' documents the canon) - the boot stage cannot package
+ #require, so keep this mapping in sync with that module:
+ #amd64->x86_64, aarch64->arm64, macos->macosx, macosx arm->arm64.
+ set parts [split [platform_generic] -]
+ set cpu [lindex $parts end]
+ set os [join [lrange $parts 0 end-1] -]
+ if {$os eq "macos"} {set os macosx}
+ switch -- $cpu {
+ amd64 {set cpu x86_64}
+ aarch64 {set cpu arm64}
+ arm {if {$os eq "macosx"} {set cpu arm64}}
+ }
+ return "${os}-${cpu}"
+ }
proc is_interactive {} {
if {"windows" eq $::tcl_platform(platform) && [package vcompare [info patchlevel] 9.0] == -1} {
#tcl 8.6 etc
@@ -801,7 +818,7 @@ apply { args {
#so we prepend to auto_path using a slightly inefficient method. Should be fine on relatively small list like this
#eventually it should just be something like 'ledit ::auto_path -1 -1 $libfolder'
if {"dev" in $package_modes} {
- set platform [::punkboot::platform_generic]
+ set platform [::punkboot::platform_punk]
#on windows - case differences dont matter - but can stop us finding path in auto_path
#on other platforms, case differences could represent different paths
#review
@@ -855,7 +872,7 @@ apply { args {
#src mode: add unbuilt source library paths from the project's src/ tree.
if {"src" in $package_modes && [info exists src_project_root] && $src_project_root ne ""} {
- set platform [::punkboot::platform_generic]
+ set platform [::punkboot::platform_punk]
set src_lib_base [file join $src_project_root src]
#src/lib and src/lib_tcl (editable library source)
foreach libsub [list lib_tcl$tclmajorv lib] {