# G-096 Tracked zig tcl buildsuite (suite_tcl90) with recovered TCLSH_PIPEREPL kit-repl capability Status: achieved 2026-07-20 Scope: src/buildsuites/ (suite_tcl90 new; samplesuite1 sketch reconciliation; VCS ignore flip), src/buildsuites/_build/ (untracked build/source area via existing _build globs), .gitignore + .fossil-settings/ignore-glob, src/scriptapps/bin/ (getzig scriptset rename), bin/ (regenerated punk-getzig wrapper twins, old names retired, AGENTS.md naming policy), bin/tools/ (untracked zig toolchains, existing), TEMP_REFERENCE/2024zig (read-only recovery origin) Goal: src/buildsuites gains its first real, VCS-tracked suite (suite_tcl90) that reproducibly builds the Tcl 9.0 windows runtime from clean sources using only project-managed tooling - a punk-getzig wrapper fetching a pinned zig into untracked bin/tools, with all transient checkouts and outputs under untracked src/buildsuites/_build - and the 2024 TCLSH_PIPEREPL tclMain patch is recovered into the suite in tracked form and rebased onto current Tcl 9 sources, so a suite-built runtime can return to a standard interactive repl after a kit-style main.tcl completes with unconsumed piped input buffered rather than eval'd. The gate default follows the G-103 kit-family policy (2026-07-20): the patched binary is ENABLED unless TCLSH_PIPEREPL=0 (opt-out; the unpatched plain build serves those wanting stock semantics) - and even enabled it is inert for scripts that never set ::tclsh(dorepl): script-arg runs default dorepl to 0 and unconsumed piped input is buffered, not eval'd, so plain scripts behave stock. Acceptance: from a clean checkout plus a punk-getzig-fetched pinned zig, the suite builds tclsh90s/tclsh90szip from a fresh core-9-0-branch checkout under src/buildsuites/_build with recipe-generated tclUuid.h and tclsh.exe.manifest (no hand-placed files) and the result reports the expected patchlevel; the recovered patch set (piperepl plus the companion tclZipfs/tclCmdIL patches and a notes doc) is tracked in the suite; the rebased piperepl build gates per the G-103 punk-kit policy: with TCLSH_PIPEREPL=0 it behaves identically to the unpatched build on a tty/piped/script-arg matrix, with the gate open (unset or any other value - the default) scripts that never touch ::tclsh(dorepl) still behave stock on the same matrix (script-arg runs default dorepl to 0; unconsumed piped input is buffered in ::tclsh(inputbuffer), not eval'd), and a script setting ::tclsh(dorepl) 1 lands in a live interactive console repl after piped-input eof with the unconsumed input available in ::tclsh(inputbuffer); src/buildsuites is tracked in both VCSes with only _build content ignored and the samplesuite1 vendorbuild-prefix residue reconciled (vendorbuild concept retired); bin/AGENTS.md documents the utility naming policy (punk- prefix for punkshell-own utilities; exceptions: external-tool wrappers such as dtplite/sdx/kettle, and getpunk as the intended future cross-platform entry point) and the getzig scriptset and its bin wrapper twins (getzig.cmd/getzig.ps1) are renamed to punk-getzig with the old names removed and references updated. ## Context - src/buildsuites (2026-07-10 sketch: samplesuite1 with a Tcl-script-style download_and_build.config carrying SOURCEDOWNLOAD/CONFIGSTART records) is blanket-ignored in BOTH VCSes today (.gitignore `/src/buildsuites`, .fossil-settings/ignore-glob `src/buildsuites`) - deliberately untracked while the sketch was non-final. User decision 2026-07-20: buildsuites is the home for build source-pull/recipe declarations ("it was essentially for this purpose"); this goal makes suite content tracked. - Untracked build/source area: src/buildsuites/_build (user 2026-07-20: "seems neater to keep it all under src/buildsuites/_build"). Already covered by the existing _build ignore globs in both VCSes (git `**/_build/`; fossil `_build` + `*/_build`) - no new ignore rules needed for it. The sketch's `/vendorbuild/` buildprefix and the root `/vendorbuilds/` ignore entries are retired in its favour. - The TCLSH_PIPEREPL patch (Aug 2024; c:/buildtcl/2024zig/build_tcl90/patch/ tclMain.c.piperepl.patch + tclMain_piperepl.c, snapshot under git-ignored TEMP_REFERENCE/2024zig) enables returning to a standard C-level tcl repl after a kit main.tcl - not possible with unmodified sources (user 2026-07-20). Semantics: gated by the TCLSH_PIPEREPL env var (unset/0 = stock behaviour); publishes ::tclsh(istty) plus linked ::tclsh(dorepl)/::tclsh(evalinput); unconsumed piped input accumulates in ::tclsh(inputbuffer) rather than being eval'd (unless evalinput is set - protects arbitrary piped data from accidental eval); on stdin eof with dorepl set, stdin reopens from the console (CONIN$ on windows, /dev/tty elsewhere) giving a live standard repl. Companion patches in the same folder: tclZipfs.patch, tclCmdIL.patch (unexamined). None of these files are VCS-tracked anywhere - recovery into the suite is the durability fix. - Recipe baseline: the validated build provenance in goals/archive/G-076-tcl9-deadconsole-fix-adoption.md (2026-07-20 entries; G-076 achieved 2026-07-20) - build90.zig / build905.zig with zig 0.14.0-dev.2074, the fresh-checkout generated-file preconditions (tclUuid.h from manifest.uuid; tclsh.exe.manifest from its .in with @TCL_WIN_VERSION@/@MACHINE@), and the 9.0.5+ mingw_unicode_entry_point requirement (upstream removed TCL_BROKEN_MAINARGS from win/tclAppInit.c). - getzig today: scriptset src/scriptapps/bin/getzig.{bash,ps1} + getzig_wrap.toml, wrapped by punk::mix::commandset::scriptwrap::multishell into bin/getzig.cmd (tracked) with a bin/getzig.ps1 twin. The twin is a deliberate polyglot-launchability artifact - windows users may start from cmd.exe or powershell - not residue. Fetches zig into bin/tools (untracked via the existing bin/* globs) with minisign signature material, sourcing ziglang.org, community-mirrors.txt and the punkbin gitea mirror. bin/tools currently holds zig 0.15.1/0.15.2/0.16.0-dev toolchains; the known-good recipe used a manual C:/zig install (0.14.0-dev.2074). - Toolchain policy (user 2026-07-20, recorded in G-076 - achieved, archived - and agent memory): zig is the only build mechanism approved to become part of the punkshell project; msys/mingw and MS toolchains are test/validation only (MS last resort). ## Approach - suite_tcl90 tracked layout: the zig recipe (build905.zig lineage, parameterized for suite paths), patches/ (piperepl + tclZipfs + tclCmdIL + a notes doc carrying the semantics summary and rebase history), suite README. Transient content under src/buildsuites/_build// (source checkouts, build prefixes/outputs); fossil clones stay in the shared ~/.fossils. - The recipe generates tclUuid.h and tclsh.exe.manifest itself (wrapfiletofile-style steps) so fresh checkouts build with no hand-placed files. - Pin an exact zig version retrievable via punk-getzig (punkbin can host the pinned zip); migrating the recipe from 0.14.0-dev.2074 to the pinned version is in-scope (zig build API churn), with the validated exact-combo build as fallback per the duplicate-first policy. - Naming policy: punk- (hyphenated) prefix approved by user 2026-07-20 over bare punk concatenation - readable, groups in listings, distinct from the punk*.exe shell-kit namespace. Applied here to getzig (touched anyway); the sweep of the remaining punkshell-own utilities is G-097. - Suite config format stays pragmatic (zig/script files); toml-based suite declarations remain a G-005-era decision - buildsuites structure beyond what this goal claims is still non-final. ## Alternatives considered - `/vendorbuild/` as the untracked build area (samplesuite1 sketch + `/vendorbuilds/` ignores) - retired 2026-07-20 in favour of src/buildsuites/_build: one area adjacent to the suites, already ignore-covered in both VCSes. - Upstreaming the piperepl capability instead of carrying a patch - not precluded as a future path; tracked in-suite recovery is the durability baseline either way and is required regardless while nothing upstream provides it. - Folding the bin-wide utility rename sweep into this goal - split to G-097 to keep this acceptance verifiable and let the sweep wait for a suitable time (user 2026-07-20). ## Notes - 2026-07-21 (post-achievement, recorded under G-097): the getzig->punk-getzig rename missed the project LAYOUT stores (src/project_layouts + modpod-templates shipped a pre-rename getzig.cmd); closed by G-097's layout fold - layouts now ship punk-getzig.cmd as a byte-copy of the current bin artifact. - Related goals: G-005 (zig build infrastructure - this suite is its first concrete increment), G-018 (zig plain tclsh kits), G-006 (prebuilt artifact download consent; punkbin mirror overlap), G-004 (no committed binaries - untracked bin/tools and _build align), G-076 (achieved 2026-07-20 - verification-runtime provenance this recipe formalizes; goals/archive/G-076-tcl9-deadconsole-fix-adoption.md), G-038 (punkshell-level piped session continuity - the punk-repl analogue of piperepl), G-060 (qemu cross-platform matrix - see G-097 notes on the windows-sandbox experiments), G-089 (scriptlib in kits; the scriptapps/bin deployment surface). - getpunk (naming-policy exception): intended future single-download cross-platform starting point - run in a new folder, the folder becomes the repo automatically; needs smarts to pull the repo and then update itself safely without snagging on the now-dirty repo (user 2026-07-20). The polyglot .cmd/.ps1 twin mechanism serves that cmd.exe-or-powershell first-contact story and may need review in that light; candidate goal when picked up. - The G-076 kill-procedure runtime (zig-out905 under c:/buildtcl/2024zig) predates this suite; once suite_tcl90 reproduces it, the ad-hoc c:/buildtcl/2024zig builds become historical reference only. - 2026-07-20 declarative sources + copy-and-tweak (user request: a developer without llm assistance retargets urls/branches declaratively): source declarations hoisted out of the driver into sources.config (plain line records 'source ', parsed never executed, critcl git pin included; -tclbranch becomes a per-run override of the declared ref) and the build stage is now derived from the suite FOLDER name so a copied tree stages into its own _build/. README gained a Retargeting/copying section (and its stale Sources section - old per-stage fossil store, missing G-098 (achieved 2026-07-20) sources - was corrected). Depth limit documented in sources.config: same-major url/ref tweaks are config-only; version-class changes ripple into build905.zig (dir names, version-derived tm/dll/manifest names). - 2026-07-20 DIRECTION (user decisions + open consideration): - toml is DROPPED as a requirement for binary-build buildsuites (plain-Tcl sources.config stands; keeps the driver dependency-free). - Long-term intent: the whole process bootstrappable WITHOUT a pre-existing tclsh. The accepted root dependency is zig acquisition (consent-gated download per G-006, or self-built zig). tcllib/tklib installers (and critcl) legitimately need a tclsh - the FRESHLY BUILT suite tclsh serves as that intermediate. - Open question raised: long-term driver for the suite.tcl functionality - zig itself vs a cross-platform polyglot (bash+powershell as inputs). Current recommendation (recorded from 2026-07-20 discussion): zig-driver hybrid - pre-tclsh phases (fetch, configure-product generation, compile) migrate into the zig build layer (build.zig.zon is itself a declarative hashed source manifest, subsuming sources.config for zig-fetched trees); post-tclsh phases (installers, critcl, test gate) stay Tcl scripts executed by the suite-built shell as build steps. Polyglot bash+powershell counselled against: two implementations (or a fragile dual-parse dialect) with divergent quoting/path semantics for exactly the string-heavy orchestration shells do worst. RESOLVED 2026-07-20: user agreed with the zig-hybrid recommendation - drafted as G-102 [proposed] (goals/G-102-buildsuite-zig-bootstrap.md). This goal's remaining items close out on the current suite.tcl shape regardless. ## Progress ### 2026-07-20 increment 1: activated; buildsuites tracked; suite_tcl90 builds 9.0.5 end-to-end - Goal set active (user 2026-07-20). VCS tracking flip: the blanket /src/buildsuites ignores removed from .gitignore and .fossil-settings/ignore-glob; the retired vendorbuilds ignores removed with them; src/buildsuites/_build confirmed ignored via the existing **/_build/ (git) and */_build (fossil) globs. - samplesuite1 sketch reconciled: marked SKETCH ONLY with the toolchain-policy note; buildprefix moved from /vendorbuild to src/buildsuites/_build/samplesuite1. - suite_tcl90 created (tracked): build905.zig verbatim from the G-076-validated recipe, helper build modules, src/main.zig stub, tools (wrapfiletofile.zig, zipfs_mkzip/mkimg.tcl), patches/ (piperepl pair + tclZipfs + tclCmdIL + README with the piperepl semantics), suite README, and the suite.tcl driver. - Driver design: the tracked recipe is STAGED into _build/suite_tcl90/build with sibling sources arranged around it (tcl905 = fossil core-9-0-branch; tclthread and tclvfs fossil trunk; zlib copied from the tcl checkout's own compat/zlib 1.3.2; vqtcl from a local dir - no public upstream confirmed), so the recipe needs no path surgery and cache/outputs land under _build naturally. Fossil checkouts open --nested (the stage is inside the punkshell checkout) with FOSSIL_HOME= so the global fossil config db records nothing; clones reuse ~/.fossils (tcl, tclthread, tclvfs all already present). - Fresh-checkout generation lives in the driver (G-076 findings productized): win/tclUuid.h from manifest.uuid; win/tclsh.exe.manifest from its .in (TCL_WIN_VERSION per the tree's own formula, parsed from tcl.h - note the defines are indented '# define'); thread.rc gains the tcl.h include for its version resource (scripted idempotent edit of the staged checkout, replacing the historical uncommitted tweak in the 2024 tclthread checkout). - Recipe fixes made in the suite copies: the four tcl-dependent helper modules' hardcoded ../tcl90/generic include (author's "todo - fix") now use their tcldir param; build_tclthread additionally puts the generated threadUuid.h's output dir on the include path - current thread trunk #includes threadUuid.h (upstream makefiles generate it into their build dir; the recipe's copy-to-source went to win/, which is not an include dir). build_libtommath.zig keeps its hardcoded path but is not called by the recipe. - End-to-end run PASS (native tclsh 9.0.3 driving; zig 0.14.0-dev.2074 at C:/zig): fetch -> stage -> generate -> build -> smoke. Static and zip shells both report 9.0.5 (checkout 1a9c3b9d96 = core-9-0-branch tip carrying the f10d91c2 console fix); zip shell tzdata working; tcl9thread301.dll builds from CURRENT thread trunk (3.0.1) and loads. vfs/vlerq dlls also built. ### 2026-07-20 increment 2: punk-getzig rename + naming policy; 0.15 migration attempted then reverted - getzig -> punk-getzig: scriptset renamed (bash/ps1/_wrap.toml; getzig_original.polyglot kept as historical reference), payload self-references updated, and the ziglang.org release URL now derives its version from the single $releasearchive pin (it carried a separately hardcoded 0.15.1 against the 0.15.2 archive). Re-wrapped via scriptwrap multishell (checkfile ERROR-free; the two boundary-scan warnings are the documented-normal polyglot ones). bin: getzig.cmd removed, punk-getzig.cmd tracked, punk-getzig.ps1 twin (byte-copy) refreshed; bin/AGENTS.md gains the punk- naming policy section (exceptions dtplite/sdx/kettle wrappers + getpunk; sweep = G-097); src/scriptapps/AGENTS.md reference updated. - zig 0.15.2 migration attempted (bin/tools/zig = the getzig-managed 0.15.2): a scripted API transform (addExecutable/addObject root_module + createModule, addShared/StaticLibrary -> addLibrary with .linkage, std.ArrayList -> std.array_list.Managed, b.host -> b.graph.host) got the recipe to compile up to a strict-format print issue, but the user flagged mid-work that the 0.14->0.16 churn is significant and the 2024 zig target comes first - REVERTED to the committed 0.14-validated recipe and re-verified PASS (9.0.5 shells, zig 0.14.0-dev.2074). The transformer script and findings are preserved (scratchpad zig015_migrate.tcl; known remaining 0.15 items: slice-of-strings debug.print format, plus whatever the next compile reveals). Pin-path decision put to the user: official 0.14.1 release as-is, punkbin-hosted 0.14.0-dev.2074, or completing the 0.15.2 migration. ### 2026-07-20 increment 3: pinned zig 0.14.1 (user-chosen path) validated, hosted on punkbin, wired as suite default - User decision: pin the first OFFICIAL release in the recipe's line - zig 0.14.1 - rather than migrating to 0.15.x now or hosting the unreleased dev.2074. Fetched from a ziglang community mirror (pkg.hexops.org; ziglang.org direct timed out), minisign-verified against the zig release key (the key punk-getzig embeds), and extracted to bin/tools/zig-x86_64-windows-0.14.1/. - Recipe compat deltas for 0.14.1, validated to keep dev.2074 working (regression PASS on both zigs): b.host -> b.graph.host; the redundant second UNICODE tclMain add into tcl_objs_static removed (0.14.1 links what dev.2074's archive semantics left unpulled); the exe's ansi tclMain copy now compiles with -UUNICODE -U_UNICODE -DTCL_ASCII_MAIN (the zig cc driver can supply windows-default defines - under 0.14.1 the "ansi" copy came out as a duplicate UNICODE compile: lld duplicate Tcl_MainExW/commons; upstream's TCL_ASCII_MAIN is the intended ascii-variant guard). - Cache discipline (user insight: zig caches have needed clearing across version changes): the driver now uses per-zig-version local caches (.zig-cache- in the staged build dir) and stages the recipe by per-item sync instead of wholesale delete (windows can hold transient locks on cache trees). During diagnosis both a fresh local AND isolated global cache were tested - the 0.14.1 duplicate-symbol failure was real recipe/driver behaviour, not stale cache, but the segregation guards the class going forward. - punkbin publish (user-directed): zig-x86_64-windows-0.14.1.zip + .minisig added to punkbin win32-x86_64/tools with sha1sums regenerated per that repo's workflow (NEW x2, no CHANGED), committed with provenance and PUSHED upstream (abcd87c) - the suite pin is now fetchable from punk-getzig's primary mirror. - suite.tcl zig resolution is now: -zig > PUNK_ZIG > pinned bin/tools/zig-x86_64-windows-0.14.1/zig.exe > PATH; verified end-to-end with no options (pinned default -> PASS, static+zip shells 9.0.5). README documents the pin, the compat deltas, and the per-version cache rationale. - The 0.15.2 migration remains parked (transformer script + findings preserved; increment-2 record). ### 2026-07-20 increment 4: vqtcl retired; Tcl-testsuite action; zig 0.16.0 migration experiment SUCCEEDS New user direction this increment: punk-getzig's 0.15.2 pin was incidental (no need to target 0.15 at all - jump to current 0.16.0 if practical); the suite should exercise the Tcl core testsuite on its built shell; Tk (core.tcl-lang.org/tk) must be built to run all punkshell tests; tcllib + critcl-built accelerators matter (tcllibc - punkcheck hashing is very slow without it); vlerq/vqtcl to be cleaned out (old-tclkit attempt; future tclkit work references TEMP_REFERENCE/metakit + TEMP_REFERENCE/KitCreator). - vqtcl/vlerq removed from the suite (wiring, helper module, staging, docs) - also removes the only non-public source dependency. Committed 1664e9ba. - New `suite.tcl test` action runs tests/all.tcl on the suite-built static shell with -testargs passthrough. Enabled by syncing the 2024-era hardcoded tm install names to the tree's provided versions (tcltest-2.5.11, http-2.10.2, platform-1.1.1 - the old names made 'package require tcltest' fail on a filename/provide conflict). - Full Tcl core testsuite on the 0.14.1-built shell: Total 66350, Passed 54825, Skipped 11453 (largely no-C-test-commands constraints in a release shell), FAILED 72. Triage of the 72 is PENDING (compare against the native-runtime baseline - memory records exec-14.3 as the only native-baseline failure on this machine; static/zipfs/no-dde-reg differences are the likely classes). Note all.tcl exited 0 despite failures - the driver should parse the totals line rather than trust the exit code (todo). - zig 0.16.0 (official, current per ziglang.org) fetched via community mirror, minisign-verified, extracted to bin/tools/zig-x86_64-windows-0.16.0. Migration EXPERIMENT (in _build/suite_tcl90/build016, tracked suite untouched): the 0.15-era transformer (root_module/createModule, addLibrary+linkage, array_list.Managed, b.graph.host) plus these 0.16 deltas: std.fs.cwd dir-walks -> std.Io.Dir.cwd() with b.graph.io threaded through (3 sites); Compile forwarders gone -> .root_module.* sweep (addCSourceFile(s)/addIncludePath/addObjectFile/addLibraryPath/linkLibrary/ addWin32ResourceFile; linkLibC() -> root_module.link_libc = true; linkSystemLibrary needs an options arg, linkSystemLibrary2 merged into it); wrapfiletofile tool ported to the 0.16 entry idiom (main(init: process.Init.Minimal), init.args.toSlice, std.Io.Threaded io instance, Io.Dir readFileAlloc/createFile, File.writeStreamingAll, cleanExit(io)); slice-of-strings debug.print loop-ified. mingw_unicode_entry_point SURVIVES in 0.16. RESULT: full build PASS under 0.16.0 (install + install-libraries + make-zipfs), both shells report 9.0.5, and the 3-file tcl-test parity run is IDENTICAL to the 0.14.1 build (557/357/200/0). - Direction assessment recorded for the user: 0.16 adoption is practical at bounded cost (one sitting); recommendation is to adopt 0.16.0 as the suite pin (deprecating 0.14 per the user's stated intent), land the ported recipe from build016, host the 0.16.0 archive on punkbin, and only then write the NEW recipe code (Tk, tcllib accelerators via critcl driving zig cc) once against the final API. Tk/tcllib/ critcl/testsuite-gating are new scope vs this goal's contract - candidate follow-on goal to draft (proposal-first). ### 2026-07-20 increment 5: zig 0.16.0 ADOPTED (user approval "as recommended") - The build016 port landed into the tracked recipe (7 files; src/main.zig unchanged). The recipe is now 0.16-API only - 0.14 support deprecated per the user's intent; the 0.14-era recipe remains in git history and zig 0.14.1 stays archived on punkbin. - suite.tcl pinned default -> bin/tools/zig-x86_64-windows-0.16.0/zig.exe; README pin + lineage sections updated (0.16 port deltas documented). Verified end-to-end on the pinned default: build PASS (9.0.5 both shells) + tcl-test parity 557/357/200/0. - punkbin: zig-x86_64-windows-0.16.0.zip + .minisig added with sha1sums regenerated (NEW x2, no CHANGED), committed 54714d7 with provenance. PUSH PENDING: the gitea remote is currently returning Internal Server Error (even ls-remote; the 0.14.1 push succeeded earlier today) - retry when the server recovers. - punk-getzig pins updated to 0.16.0 in both payloads (ps1 $releasearchive, bash tarball zig-x86_64-linux-0.16.0.tar.xz), re-wrapped (checkfile ERROR-free), .ps1 twin refreshed. Its next run will replace bin/tools/zig (active 0.15.2) with 0.16.0. Remaining for acceptance: - punk-getzig per-version fetch argument, so the wrapper itself can materialize arbitrary pinned versions into versioned dirs (payload growth needs the 512-byte spacer check on re-wrap). - DONE 2026-07-20 (see the Progress increment): piperepl rebase + variant builds + behaviour matrix. (Acceptance/Goal wording was first aligned to the G-103 kit-default policy at user request - the pre-G-103 text described the 2024 opt-in gating.) Residual user-level check DONE (user 2026-07-20): true interactive sessions on tclsh90spr behave normally both with TCLSH_PIPEREPL=0 and without. The user additionally exercised punk on the bare pr shell (tcl::tm::add repo modules; package require repl; repl::init; repl::start stdin - basic punk features functional; raw mode is twapi-reliant), and via './tclsh90spr src/make.tcl shell' the powershell console-mode fallback engaged and raw mode worked (noise/early-shutdown roughness aside) - fallback maintenance now tracked as G-106. - Final clean-checkout re-verification of the whole flow once the above land. ### 2026-07-20 increment: piperepl rebased, gate flipped to G-103 policy, variants built + matrix PASS - Rebase was clean: the recovered 2024 patch applies to current core-9-0-branch (9.0.5) tclMain.c with all 8 hunks at offset 4. Tracked as patches/tclMain_piperepl_905.c (stock + patch + gate flip + provenance banner); the 2024 era files are kept unmodified as recovered artifacts. - Gate default flipped per the G-103 punk-kit policy: hasPipeRepl is now (s == NULL) || strcmp(s, "0") - ENABLED unless TCLSH_PIPEREPL=0 (2024 original was opt-in set-and-not-"0"). Goal/Acceptance wording aligned first, at user request, before the rebase landed. - Products: build905.zig gains tclsh90spr (same per-source construction as tclsh90s with both tclMain compiles - unicode + TCL_ASCII_MAIN ansi - swapped to the patched file) and tclsh90sprzip (zipfs_mkimg wrap of the pr exe with the tcl library attached, -infile form). Stock products remain byte-for-byte unpatched. patches/ added to the suite.tcl staging list. Full suite build PASS (9.0.5 checkout 1a9c3b9d96, zig 0.16.0) with the new products installed. - Behaviour matrix (tclsh90s vs tclsh90spr; env unset / =0 / =1): - script-arg, script-consuming-stdin, and piped-commands forms: OUTPUT+EXITCODE IDENTICAL across all 9 combinations - including the key open-gate rows (a plain script never touching ::tclsh(dorepl) behaves stock; piped payload a script left unread is NOT eval'd - 'puts SHOULD-NOT-EVAL' payload never executed). - Feature row (script sets ::tclsh(dorepl) 1, piped payload unread, gate open): payload lines buffered VERBATIM into ::tclsh(inputbuffer) (proven via a write trace firing when the C code publishes the buffer: BUFFER), '? reopen stdin from console' emitted, CONIN$ reopen succeeded and the repl landed (in an uninstrumented run the process sits live at the prompt reading the console - observed as the harness timeout; the trace variant exits deterministically pre-prompt). - Same feature row with TCLSH_PIPEREPL=0: identical to stock (script-ran, rc 0, no ::tclsh machinery). - tclsh90sprzip: identical feature behaviour to tclsh90spr - the attached-lib kit-style form works, i.e. the G-103 punk-kit precursor. - Known divergence documented in patches/README.md: with the gate open, tcl_interactive is LINKED before the startup script runs (stock links at repl entry), so scripts that WRITE ::tcl_interactive can influence prompting where stock ignores the write until repl entry; readers see identical values. ### 2026-07-20 increment: punk-getzig per-version fetch into versioned dirs - all four paths verified - The scriptset (src/scriptapps/bin/punk-getzig.ps1/.bash) takes the zig version as the first argument (default = the suite pin, 0.16.0) and installs into tools/zig-x86_64-windows- - the zip's OWN root folder name, so the old rename-into-place step (and its post-ExtractToDirectory lock retry/GC dance) is gone entirely. Installed-check reports a mismatch warning if the exe's reported version differs from its versioned folder. Documented limitations: dev builds (/builds/ url space) and pre-0.14.1 releases (old zig-- archive naming) are not handled - punkbin's flat tools/ mirror path serves those if one must be pinned. The bash side remains an honest stub with the same argument convention. - Rewrapped via punk::mix::commandset::scriptwrap::multishell (punk905_beta src script) -> bin/punk-getzig.cmd regenerated + .ps1 twin byte-synced; no spacer issues (template label-analysis warnings are the known pre-existing noise). - VERIFIED all four paths through the polyglot wrapper: (1) explicit present version: 'punk-getzig.cmd 0.16.0' -> versioned dir found, reported version matches, early exit; (2) no-arg default: resolves 0.16.0 identically; (3) existing-zip path: 'punk-getzig.cmd 0.15.2' with the zip+minisig present but no dir -> signature verified -> extracted to zig-x86_64-windows-0.15.2 -> ZIG VERSION: 0.15.2; (4) FULL NETWORK path: 0.15.2 zip/minisig/dir removed (backed up first) -> mirror-latency selection picked the local punkbin dev mirror -> zip + minisig downloaded -> signature verified -> versioned extract -> ZIG VERSION: 0.15.2. - Remaining for this goal: the final clean-checkout re-verification only. ### 2026-07-20 increment: final clean-checkout re-verification PASS - all acceptance items met - Flow: fresh git clone of the repo (at 9496a898) -> the CLONE'S OWN bin/punk-getzig.cmd (empty bin/tools; real 0.16.0 fetch via the mirror chain, minisign-verified, versioned dir) -> suite.tcl build with a cold zig cache -> 'suite_tcl90: PASS - built 9.0.5 (checkout 1a9c3b9d96, zig 0.16.0)' with recipe-generated tclUuid.h + tclsh.exe.manifest (TCL_WIN_VERSION 9.0.2.905), static + zip + pr + przip shells produced, zip shell smoked (9.0.5, tz set), tk/tklib/tcllib/tcllibc legs all completed in the clone. - CAVEAT recorded: the first attempt (clone under the deep agent-scratchpad path) failed at checkout with windows MAX_PATH 'Filename too long' on the modpod template trees - a clean checkout of this repo on windows needs a SHALLOW base path and/or git core.longpaths=true (same MAX_PATH class as the known project.new-outdir trap). Verified from C:/Users//AppData/Local/Temp/pkverify with -c core.longpaths=true. - Cold-build log oddity diagnosed as BENIGN and then removed at source: zig 0.16's build_runner prints a 'failed command:' block for any step whose result_stderr is nonempty EVEN ON SUCCESS (build_runner.zig prints error/warning messages when result_stderr.len > 0 regardless of result). Our zipfs_mkzip/zipfs_mkimg call echoes and wrapfiletofile's octet count went to stderr, so uncached (cold) runs showed four alarming-but-successful 'failed command' blocks (warm runs fewer - cached steps don't re-run). The informational prints now go to stdout (or are removed); a rebuild shows zero 'failed command' occurrences with PASS. - With this, every Acceptance item is met: clean-checkout + punk-getzig-pinned-zig build (this increment), recovered+rebased patch set with the G-103 gate policy and behaviour matrix (earlier increments), both-VCS tracking + samplesuite1/ vendorbuild reconciliation, bin/AGENTS.md naming policy + punk-getzig rename (original increments). Ready for the achieved flip on user confirmation.