From d953ce5c072d1154fdcec48dae973ba775f4f3bc Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Fri, 31 Jul 2026 20:14:28 +1000 Subject: [PATCH] G-127 increment 4: docs + records; punkshell 0.39.0 - bin/AGENTS.md: "Cross-target kit outputs (bin/kits//)" contract section (locations, coexistence, ignore coverage, relocations + orphan note) - src/AGENTS.md: target-keyed output bullet beside the G-122 host/target material (locations, name-spanning selection, %platform% payload axis) - make.tcl workflow text per its update contract: [K9] output split, [K8] untracked additions, .vfs.toml %platform% line; bakelist helptext + report header name the kits// tier (both renders verified, width ok) - punkproject.toml 0.38.0 -> 0.39.0 + CHANGELOG entry (minor bump: new declaration capability + relocated cross-target outputs) - goal detail Progress: G-023 reconciliation stated (versioned outputs compose with the platform tier; release gate checks per-kit deploy dir), punkshell902 + verify-ix86 relocation records finalized, punk9linux migration decision recorded (declared where a governed tier exists, hand-curated tcltls/tdom/ thread drop-ins pending G-116/G-004) Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- CHANGELOG.md | 24 ++++++++++++++++++ bin/AGENTS.md | 28 +++++++++++++++++++++ goals/G-127-crosstarget-vfs-bake.md | 38 ++++++++++++++++++++++++++--- punkproject.toml | 2 +- src/AGENTS.md | 1 + src/make.tcl | 23 ++++++++++++++--- 6 files changed, 108 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63df75c5..af8109b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,30 @@ 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.39.0] - 2026-07-31 + +- Target-keyed kit output locations (G-127): a kit whose mapvfs entry declares + a target other than the host's default now builds under + `src/_build/kits//` and deploys under `bin/kits//` + (per-tier punkcheck ledger; sidecar, arch scan, offset probe, smoke probe + and sweep guards follow), while default-target kits keep their flat + locations byte-identically. Same-named kits for different targets coexist - + the pre-G-127 cross-run overwrite and runtime-name disambiguation for + cross-target namesakes are gone; a kit name spanning targets selects all of + them in `bakelist` and selective `bake`. `bakelist` marks such rows with + `out=kits//` and prints tiered paths in the detail block. + RELOCATIONS: linux `punkshell902` -> `bin/kits/linux-x86_64/punkshell902`; + the `verify-ix86` kits land at `bin/kits/win32-ix86/` on their next bake + (pre-move flat copies are orphans to remove by hand). +- Per-platform payload declarations (G-127 on the G-115 surface): a + `[payload.*]` source containing `%platform%` materializes once per CONSUMING + kit target (platform set derived from the kit mapping) into VCS-ignored + `_targets//` staging inside the `.vfs` folder, and each kit's + merged image receives only its own target's subtree. punk9linux.vfs's + tcllibc entry migrated to the axis and its flat committed + `lib_tcl9/tcllibc` tree was removed from VCS (the packages tier and the + declaration govern it). + ## [0.38.0] - 2026-07-31 - Kit mapping converted to toml (G-024, achieved): `src/runtime/mapvfs.toml` diff --git a/bin/AGENTS.md b/bin/AGENTS.md index 99dd1c79..fbffd6e5 100644 --- a/bin/AGENTS.md +++ b/bin/AGENTS.md @@ -170,6 +170,34 @@ set; and an unclassifiable binary is silence, not a pass. A kit whose bake recap showed no `BUILD-WARNING`s still only proves what those checks measure - not that every payload package loads. +### Cross-target kit outputs (`bin/kits//`, G-127) + +Kit OUTPUT locations are keyed by each kit's TARGET platform (the mapping's `target` +key - G-122's output half): + +- A kit for this host's own default target deploys flat to `bin/` exactly as + always (build product `src/_build/`). +- Any other target's kit deploys to `bin/kits//` (build product + `src/_build/kits//`), each tier with its own `.punkcheck` install + ledger and the `.resources.toml` sidecar beside the kit as usual. `bin/kits/` + rather than `bin//` because `bin/runtime//` already means build + INPUTS - the two tiers sit side by side as input vs output. +- Same-named kits for DIFFERENT targets therefore coexist (the artifact path is a + pure function of name + target, and `.exe` suffixing follows the target); only a + same-name same-TARGET duplicate gets the historical `_` rename. +- `make.tcl bakelist` marks non-default-target rows with `out=kits//` and + its per-kit detail block prints the tiered paths; a kit NAME spanning several + targets selects all of them (bakelist and selective bake alike). +- Everything under `bin/kits/` is a build output covered by the existing `/bin/*` + ignore rules in both VCS - never commit from it. +- Relocations at the 2026-07-31 switch: the linux `punkshell902` moved from + `bin/punkshell902` to `bin/kits/linux-x86_64/punkshell902` (intended relocation - + G-127), and the `verify-ix86` kits (`punkluck86`, `punk91ix86`, target + `win32-ix86`) land at `bin/kits/win32-ix86/` on their next bake. Pre-move flat + copies are orphans - remove them by hand. +- Characterization: `src/tests/shell/testsuites/punkexe/maketclkitlocations.test` + (fixture mappings via `PUNK_MAPVFS_CONFIG`). + ### Kit resource record sidecar + embedded icon (G-057) Every kit a bake builds ships with a `bin/.resources.toml` text diff --git a/goals/G-127-crosstarget-vfs-bake.md b/goals/G-127-crosstarget-vfs-bake.md index 76cb2fbf..6d72bf00 100644 --- a/goals/G-127-crosstarget-vfs-bake.md +++ b/goals/G-127-crosstarget-vfs-bake.md @@ -264,8 +264,38 @@ exists locally (empty but for sha1sums.txt) and punkbin upstream carries the @group branch, so filtered bakelist detail and selective bake cover every target of a shared name. Full punkexe subtree green: 15 files, 101 tests, 97 pass / 4 constraint-skips / 0 fail (88s, native Tcl903 runner). +- 2026-07-31 increment 4 (docs + records; punkshell 0.39.0): + bin/AGENTS.md gains the "Cross-target kit outputs (bin/kits//)" + contract section; src/AGENTS.md gains the target-keyed-output bullet beside + its G-122 host/target material; make.tcl workflow text updated per its update + contract ([K9] output split, [K8] untracked additions, the .vfs.toml + %platform% line, bakelist helptext + report header); punkproject.toml bumped + 0.38.0 -> 0.39.0 with the CHANGELOG entry (minor: new declaration capability + + relocated cross-target outputs). + G-023 RECONCILIATION (per Acceptance): version-named outputs COMPOSE with the + platform tier rather than competing - scheme-expanded records carry a target + like any entry and flow through the same per-kit location logic with no + special-casing, so a versioned scheme declaring target

yields + bin/kits/

/punk- etc, and the G-023 release gate now checks + the per-kit deploy dir (kit_deploydir) rather than flat bin/. G-023's own + Acceptance naming bin/punk9-0.5.0.exe stays untouched: its outputs are + default-target today, and location only moves if a target is declared. + RELOCATION RECORDS (per Acceptance): punkshell902's move bin/punkshell902 -> + bin/kits/linux-x86_64/punkshell902 is an INTENDED RELOCATION (executed live + 2026-07-31, increment 1); the verify-ix86 kits (punkluck86, punk91ix86) + relocate to bin/kits/win32-ix86/ on their next bake as the same rule's + consequence. Pre-move flat copies (bin/punkshell902, src/_build/punkshell902 + + .vfs image; later the flat ix86 kit copies) are orphans for manual removal + - also recorded in bin/AGENTS.md. + PUNK9LINUX MIGRATION DECISION (per Acceptance): punk9linux.vfs is MIGRATED to + the declaration for its tier-available payload - tcllib2.0 (neutral, G-115) + and tcllibc (per-platform %platform%, this goal; flat committed copy removed + from VCS) - while its remaining binary payload (tcltls, tdom, thread3.0.2 + .so trees) DELIBERATELY STAYS HAND-CURATED until punkbin lib-tier artifacts + exist for those packages (suite-built tcltls is G-116's scope; the general + vendored-tree migration is G-004's recorded template). Mixed posture is the + honest record: declared where a governed source tier exists, hand-curated + drop-ins where none does yet. - Remaining for acceptance: byte-comparability spot-check for a zip-type native - kit; bin/AGENTS.md + src/AGENTS.md output-location docs; G-023 reconciliation - statement recorded here; punkshell902 + win32-ix86 relocation records - finalized; punk9linux.vfs remaining drop-ins (tcltls/tdom/thread .so) - recorded as deliberately hand-curated or migrated. + kit (prefix + extracted-content comparison); full-suite/punkexe re-run at + closeout. diff --git a/punkproject.toml b/punkproject.toml index 45fc3911..7d6b07d2 100644 --- a/punkproject.toml +++ b/punkproject.toml @@ -1,6 +1,6 @@ [project] name = "punkshell" -version = "0.38.0" +version = "0.39.0" license = "BSD-2-Clause" url = "https://www.gitea1.intx.com.au/jn/punkshell" #packager: declared identity for published artifacts (declarative, not proof - diff --git a/src/AGENTS.md b/src/AGENTS.md index 4a7c0fe4..0282968a 100644 --- a/src/AGENTS.md +++ b/src/AGENTS.md @@ -77,6 +77,7 @@ Recovery after a wrong path guess: - Kit bakes consume the punk-runtime WORKING COPIES under `bin/runtime//`: `make.tcl bake`/`bakehouse` emit a `BUILD-WARNING:` (recapped at end of run) when a wrapped runtime's beside-toml revision is older than an `-r` artifact present in the same folder - the forgot-to-switch-back guard for deliberate `punk-runtime use ` testing excursions. Heed it before trusting freshly baked family kits; `bin/punk-runtime.cmd use >` (`.exe` suffix optional) re-materializes the working copy. - `tclsh src/make.tcl bakelist ?kitname|@group ...?` (G-121/G-024) reports the kit outputs configured in `src/runtime/mapvfs.toml`: kit name, kit type, runtime (with presence in the runtime store), vfs folder, and the deployed state of `bin/` vs the `src/_build` build product (`current|stale|absent|nobuild`), with anomalies (`runtime=missing`, `vfs=missing`, `rtrev=r` materialization staleness), the cross-target marker `target=`, groups (`group=`), full-bake exclusion (`default=no`) and scheme roles (`scheme=versioned|dev|release`) in a trailing notes column. A nonexistent store tier is flagged loudly per tier actually referenced (header `(FOLDER MISSING)` for the default tier + stderr derivation; bake's no-runtimes exit self-diagnoses the same way). Name/@group arguments filter the report and add a per-kit detail block (resolved store tier, target and provenance of the target, config entry, group, paths/sizes/mtimes). `make.tcl bake ?kitname|@group ...?` bakes and deploys only the named kits - other kits' `_build`/`bin` artifacts and punkcheck records are untouched and the vfslibs phase narrows to the named kits' vfs folders; an unknown name errors before any build, listing the configured names and groups; flags go before kit names (`make.tcl bake -confirm 0 punk91`). Bare `bake` processes all configured kits except `bake_default=false` entries; a `versioned`-scheme release output (plain `punk` name) is created when absent and otherwise skipped - a normal bake never overwrites it (the explicit release step is G-023's). Both surfaces consume the shared parsed-mapping helpers (`::punkboot::lib::mapvfs_*`) rather than the file format (G-024: toml reader canonical, deprecated `mapvfs.config` line reader retained as fallback; `PUNK_MAPVFS_CONFIG` env points at an alternate config for characterization). Piped characterization: `src/tests/shell/testsuites/punkexe/maketclbakelist.test`. - **Host vs target platform (G-122).** Everything a bake EMITS is keyed by the artifact's TARGET platform, never by the driving tclsh's personality: the `bin/runtime/` store the runtime is read from, `.exe` suffixing of runtime files and kit outputs, the presence checks behind `runtime=missing`, and whether the pre-deploy process sweep uses `tasklist`/`taskkill` or `ps`/`kill`. Host semantics - copy commands, path handling, filesystem case rules, prompts - stay keyed to the host. The default target is the host's own platform canon, EXCEPT a cygwin-family host (an msys2/cygwin-runtime tclsh, which reports `tcl_platform(platform)` `unix` on windows and canonizes as `msys-x86_64`/`cygwin-x86_64`), which targets `win32-x86_64`: such a host now drives the identical kit set, names and store addressing as a native tclsh. `tclsh src/make.tcl check` prints the derivation on one `platform (G-122): host=... target=... store=... exe-suffix=... process-tooling=...` line. A mapvfs entry may declare its own target platform (`target` key - see `src/runtime/AGENTS.md`), which is then read from that platform's tier, named with that platform's executable convention, and skipped by the process sweep (its processes are not visible to this host). Traps this closes, all field-verified 2026-07-26: msys `ps` cannot see a natively-launched kit (only `tasklist` can), and msys2 rewrites arguments that look like absolute posix paths when spawning a native windows program - so `taskkill /PID ` arrived as `taskkill C://PID `; native-windows command lines therefore go through `::punkboot::exec_nativeargs` (sets `MSYS2_ARG_CONV_EXCL=*`, inert elsewhere). Also note a cygwin-family tclsh is a POSIX Tcl: name the script the way that shell spells paths (`tclsh /c/repo/.../src/make.tcl`, not `C:/repo/...`, which it resolves relative to the cwd) - make.tcl diagnoses the windows-spelling case. Piped characterization: `src/tests/shell/testsuites/punkexe/maketclplatform.test` (the cygwin-host tests self-gate on finding and probing a real msys/cygwin tclsh; `PUNK_MSYS_TCLSH` names one explicitly). +- **Target-keyed kit OUTPUT locations (G-127) - the output half of the G-122 split.** A kit for the host's default target builds to `src/_build/` and deploys to `bin/` exactly as always; any other target's kit builds under `src/_build/kits//` and deploys under `bin/kits//` (per-tier `.punkcheck` ledger; the merged `.vfs` image, resource sidecar, arch scan, offset probe, smoke probe and process-sweep guards all follow the per-kit location). Same-named kits for different targets coexist - the artifact path is a pure function of (name, target) and `.exe` suffixing follows the target - so separate selective bakes can never overwrite each other's cross-target artifacts; only a same-name same-TARGET duplicate keeps the `_` disambiguation. A kit NAME matching several targets' entries selects all of them (bakelist and selective bake). Per-.vfs payload declarations gain the same axis: a `[payload.*]` source containing `%platform%` materializes once per CONSUMING kit target into `_targets//` staging inside the `.vfs` folder (VCS-ignored), and each kit's merged image receives only its own target's subtree upstream of the arch scan and G-125 gate (`src/vfs/README.md` "Per-platform entries"). Characterization: `src/tests/shell/testsuites/punkexe/maketclkitlocations.test`; output-tier contract for consumers: `bin/AGENTS.md` "Cross-target kit outputs". - Zip-type kit assembly does not require zipfs in the driving tcl (G-122): with `tcl::zipfs::mkimg` present it is used as before, otherwise the image is assembled by concatenation (raw-runtime split + `punk::zip::mkzip` + append, the same `::punkboot::assemble_zipcat_image` helper the `zipcat` kit type uses). Both mount identically - tcl zipfs reads the archive with archive-start-relative offsets. - Neither is EXTRACTING the runtime's own attached zip (needed to carry its `tcl_library` into the kit): `punk::zip` >= 0.2.0 reads a zip with stock Tcl only - no zipfs, no vfs::zip, no tcllib (G-124, the former tcllib `zipfile::decode` dependency is gone). The zipfs-less bake path splits off the executable prefix with `punk::zip::extract_preamble` and then reads the MEMBERS from the original runtime with `punk::zip::unzip`, never from the split-off intermediate: a runtime whose zip offsets are file-relative (the historical `zipfs mkimg` convention - `tclsh90b4_piperepl.exe` in the store is one) splits into a .zip whose offsets still count from the removed prefix, which plain zip readers reject. Reading the whole file at the derived base offset makes the two offset conventions indistinguishable to callers; `punk::zip::archive_info ` reports which one a given artifact uses. Verified 2026-07-26 by baking a zip kit from msys2's `/usr/bin/tclsh8.6` (no zipfs, no vfs::zip, no tcllib) and booting the result with its `tcl_library` present. - What the RUNTIME must provide to be zip-kit-wrappable - which zipfs commands, mount conventions and startup hooks are supported - is documented in `bin/AGENTS.md` "Kit-wrappable runtime requirements (G-129)". Short form: `tcl::zipfs::mount` with pairwise no-arg output (`tcl::zipfs::root` NOT required), any attached-archive mount point (the boot derives it from the runtime's own mount table - the androwish/undroidwish 8.6 backport mounts at the executable's own path), a `main.tcl`/`app/main.tcl` startup hook, and a liftable library payload for the G-125 gate. The bake's runtime capability probe keys `has_zipfs` on `tcl::zipfs::mount` accordingly. diff --git a/src/make.tcl b/src/make.tcl index caeea7ba..08d72dcf 100644 --- a/src/make.tcl +++ b/src/make.tcl @@ -2736,7 +2736,11 @@ DIAGRAM 2 - KIT ASSEMBLY DETAIL (the 'make.tcl bake' stage; incl. vfslibs phase) entries materialized INTO the .vfs folder by the vfslibs phase (vendor trees / bin/packages tier), punkcheck- tracked with drop-in-wins precedence - undeclared or - hand-modified files are preserved, never overwritten + hand-modified files are preserved, never overwritten. + A source containing %platform% materializes once per + CONSUMING KIT TARGET (set derived from mapvfs) into + _targets// staging; each kit's merged image + then gets only its own target's subtree (G-127) _vfscommon.vfs .vfs <-- payload declarations (if any) already | | materialized by the vfslibs phase @@ -2851,7 +2855,9 @@ KEY / NOTES [K8] What is VCS-tracked where (checkin targets after a build): tracked: src/** (sources, src/bootsupport, src/project_layouts copies, src/vfs/_vfscommon.vfs), punkproject.toml, CHANGELOG.md - untracked: modules*/ lib*/ at projectroot, src/_build/, bin/.exe + untracked: modules*/ lib*/ at projectroot, src/_build/, bin/.exe, + bin/kits// (cross-target kit outputs - G-127), + src/vfs/*.vfs/_targets/ (per-platform payload staging) (bin/ scripts/tools are tracked; kit executables are not) [K9] HOST vs TARGET platform (G-122). What a bake EMITS is keyed by the target @@ -2866,6 +2872,12 @@ KEY / NOTES process sweep. 'make.tcl check' prints the derivation; 'make.tcl bakelist' shows per-kit targets, with a target= note on rows that are not on the default target. + OUTPUT locations are target-keyed too (G-127): default-target kits keep the + flat src/_build/ + bin/ locations, any other target's kit builds + and deploys under the kits// tier of both (bin/kits/ = outputs, + beside bin/runtime/ = inputs), so same-named kits for different targets + coexist instead of overwriting each other; bakelist marks such rows with + out=kits// and its detail block prints the tiered paths. [K10] BOOT-PRECONDITION gate (G-125). A kit whose merged vfs has no tcl library cannot initialise at all ('Cannot find a usable init.tcl'), so the bake @@ -3108,6 +3120,11 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO default - 'make.tcl check' shows that default), G-024 groups (group=), entries excluded from full bakes (default=no) and scheme-expanded outputs (scheme=versioned|dev|release). + Non-default-target kits build and deploy under the + kits// tier of src/_build and bin (G-127) - their rows + carry out=kits// and the deployed state compares the + tiered paths; a kit NAME shared by entries for several targets + selects (and lists) every one of them. kitname (or @groupname) arguments filter the report to the named entries (per-kit detail, with resolved store tier, target, config entry and paths). Reporting only - never builds." @@ -4765,7 +4782,7 @@ if {$::punkboot::command eq "bakelist"} { append map_display " (deprecated format)" } } - puts stdout "# mapvfs: $map_display runtimes: bin/runtime/$rt_os_arch$rt_store_note deployed: bin/ vs src/_build/" + puts stdout "# mapvfs: $map_display runtimes: bin/runtime/$rt_os_arch$rt_store_note deployed: bin/ vs src/_build/ (out= rows: under kits//)" set headline "" foreach h $headings w $widths { append headline [format "%-*s " $w $h]