Browse Source

Goals: draft G-153 metakit_punk zig port (user-approved); CRT/floor notes

G-153 [proposed]: fork-as-upstream metakit port under the pinned zig -
standalone core + Mk4tcl dll/static shapes, win32-x86_64 + win32-ix86
from day one, KitCreator patch audit vs the 2.4.9.8 baseline, dll smoke
under suite-built tclsh86t (the sdx-circularity probe enabler), mk4
x64<->ix86 interchange check, and ready-to-land sources.config/zon
record text for suite consumption. Non-contract Notes: G-101 records
metakit_punk as the mk4 porting vehicle superseding the TEMP_REFERENCE
metakit trees; G-130 gains the measured UCRT linkage + OS-floor
statement (Win10 zero-prereq, Win7/8.x need KB2999226, XP/2000
structurally out), the Windows 2000 placement with the luck-specimen
Win2k-clean import measurement, the SSE2 (pentium4) cpu-baseline rider,
and the lane-mechanics inventory (standardTargetOptions present;
critcl/baselines/punkres-PE32/punkbin-folder/twapi-x86 gaps); G-131
points at G-153 for its metakit arm. goals_lint clean.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 1 week ago
parent
commit
0469374498
  1. 4
      GOALS.md
  2. 15
      goals/G-101-tcl86-kit-container-strategy.md
  3. 59
      goals/G-130-32bit-windows-buildsuites.md
  4. 5
      goals/G-131-boot-payload-autodetection.md
  5. 136
      goals/G-153-metakit-punk-zig-port.md

4
GOALS.md

@ -422,3 +422,7 @@ Detail: goals/G-151-punkargs-annotated-success-render.md
Scope: src/modules/punk/args-999999.0a1.0.tm (multiform failure classification + noformmatch errorcode/formstatus consumer contract + render marking); src/tests/modules/punk/args/testsuites/args/
Detail: goals/G-152-punkargs-form-viability-verdict.md
### G-153 [proposed] metakit_punk zig port: fork-as-upstream Mk4tcl for the 8.6 kit container
Scope: external fork repo c:/repo/jn/metakit_punk (gitea jn/metakit - the port itself lands there); src/buildsuites/suite_tcl86/sources.config and src/buildsuites/suite_tcl86/build.zig.zon (ready-to-land metakit records drafted in the detail file; landing them is G-101-era consumption); TEMP_REFERENCE/{metakit_jnorthrup,metakit_pooryorick,KitCreator} (read-only patch/boot-chain reference - machine-local); goals/G-101-tcl86-kit-container-strategy.md (consumer decision record)
Detail: goals/G-153-metakit-punk-zig-port.md

15
goals/G-101-tcl86-kit-container-strategy.md

@ -164,6 +164,21 @@ unblocked; activation is the user's call.
make the end-to-end demonstration wrap a SEPARATE COPY of the runtime so the
self-mount shadowing path is actually exercised rather than accidentally
avoided.
- 2026-08-02: the mk4 candidate gained its porting vehicle - c:/repo/jn/metakit_punk
(git; gitea jn/metakit), a punkshell-maintained fork seeded 2026-07-30 with
read-only reference snapshots of BOTH upstreams (jnorthrup 2.4.9.7 mirror,
pooryorick 2.4.9.8 porting baseline), a provenance table, and a port-relevant
fork-difference analysis - superseding TEMP_REFERENCE/metakit_jnorthrup as the
metakit reference of record (the TEMP_REFERENCE trees named in Scope remain
convenient machine-local clones; the fork repo is the versioned home). The
leadup port work is drafted as G-153 (proposed): standalone zig build (core +
Mk4tcl dll/static shapes, win32-x86_64 + win32-ix86 from day one per G-130),
the KitCreator patch-lineage audit this file flags as a required step, the
sdx-under-tclsh86t circularity probe enabler (option (a) in the sdx section),
and ready-to-land sources.config/zon record text for suite consumption. The
fork/suite boundary is held there: the fork owns the storage engine + mk::*
binding only; kit boot machinery (kitInit/boot.tcl/setupvfs analogs) stays
THIS goal's suite-side territory, and mk4vfs.tcl ships with tclvfs.
## Reference material (TEMP_REFERENCE, machine-local)

59
goals/G-130-32bit-windows-buildsuites.md

@ -91,3 +91,62 @@ the other's generation.
and the kits' smoke-require declarations (punkluck86 Thread; punk91ix86 Thread iocp)
probe resolution inside the built 32-bit artifacts - see
goals/archive/G-133-bake-payload-consistency-checks.md.
- 2026-08-02 CRT MEASURED (dumpbin /dependents import tables, recorded from the G-153
planning session) - the floor statement this goal's artifacts inherit. All zig-built
suite binaries (tclsh9.0.5*.exe family, tclsh905.exe, suite_tcl86 tclsh86ts.exe /
tclsh86t.exe / tcl86t.dll) link the UCRT dynamically (api-ms-win-crt-*-l1-1-0
forwarders) plus classic OS dlls only (KERNEL32/USER32/ADVAPI32/NETAPI32/USERENV/
WS2_32 - no api-ms-win-core-* sets in the static imports); bin/punkzip.exe (pure zig)
imports ntdll + kernel32 only, no CRT at all; the third-party prebuilts this goal
replaces (tclkit86bi.exe, tclkit-win64-dyn.exe, tclsh8.6.10-luck-zip.exe) link
msvcrt.dll (old-mingw flavor); tclsh9.1b0-tclsfe.exe links UCRT PLUS VCRUNTIME140
(MSVC build - needs the full VC++ redist, a heavier deployment story than ours).
CONSEQUENCE: Windows 10+ runs suite artifacts with zero prerequisites (UCRT inbox);
Windows 7 SP1 / 8.x need the UCRT update KB2999226 (broadly distributed via Windows
Update since 2015; app-local UCRT deployment exists but clashes with single-file
kits); XP and Windows 2000 are structurally unreachable - UCRT never existed there
and zig's bundled mingw-w64 is UCRT-flavored only (the msvcrt CRT flavor is a
mingw-w64 build-time choice, not a zig flag). The msvcrt-era "runs on anything since
1998" property of the old tclkits is NOT reproducible by this goal's artifacts -
a recorded trade-off, not an omission. Runtime GetProcAddress-based API use is
invisible to import tables, so the floor's acceptance proof remains booting the
built shell on a real minimum-version machine or VM.
- 2026-08-02 Windows 2000 placement (user question) + the measured nuance: Win2k sits
below the same UCRT wall as XP for suite builds, and Tcl 8.6's own documented floor
is XP-era (8.4/8.5 were the last Win2k-supported lines; punk modules need 8.6+
regardless). BUT the luck 8.6.10 specimen's static import surface was measured
Win2k-clean: every kernel32 import is NT4/2000-era (no AttachConsole /
GetNativeSystemInfo / GetModuleHandleEx / AddVectoredExceptionHandler /
SetDllDirectory), msvcrt usage is VC6-era (__wgetmainargs startup; no
_aligned_malloc, no _strtoi64) - so any genuine Win2k need is served by hosted
third-party/period artifacts through the G-123 tier (provenance sidecars, consent
gate), never by a suite lane; punkshell reaches such machines remotely. Unverified
on real metal (loader-level evidence only).
- 2026-08-02 CPU baseline rider: zig's 32-bit x86 baseline cpu model is pentium4, so
SSE2 is assumed by default codegen - excluding Pentium III / Athlon XP class
hardware even on OS versions the floor above covers. Proposed lane baseline: SSE2
(matches Windows 8+ hardware requirements and near-all surviving Win7 machines);
going below (-Dcpu=pentium3, x87 float paths) is possible in zig but untested and
only worth opening if pre-SSE2 retro hardware becomes a stated punkshell goal -
same archival bucket as Win2k. Record the chosen baseline in the G-103 metadata /
runtime toml alongside the target when artifacts land.
- 2026-08-02 lane-mechanics inventory (verified in-tree; complements the G-105
dependency): build86.zig already takes b.standardTargetOptions so the -Dtarget axis
exists at the zig level; the gaps are suite.tcl -target passthrough with
target-keyed staging/output prefixes, per-target expected_test_failures baselines
(+ a first 32-bit census - WoW64 runs the gates natively on the x64 host, so
post-tclsh phases including tcllib/tklib installers and critcl run UNDER the built
32-bit shell itself, no WSL analog needed), a win32-ix86-zig section in
critcl_zig.config (compile/link -target x86-windows-gnu; the critcl PATH-probe trap
is why the explicit section must exist), punkres PE32-vs-PE32+ stamping
verification before 32-bit kits are stamped (G-128, achieved 2026-07-29 - see
goals/archive/G-128-portable-pe-resource-stamping.md - measured x64 only), arch-scan
target-awareness for the kit era (an x64 dll in an ix86 kit is the defect - the
inversion of the known zint case), a punkbin win32-ix86 folder at first publish
(same motion as the recorded linux-arm64 note in G-105), and twapi-for-x86 as the
9-line kit payload open item (the 8.6 runtime is twapi-less already; this goal's
own acceptance uses the luck-shipped twapi 4.7.2 32-bit dll as the load target).
First-exe firewall consent applies per new artifact path as usual. G-153
(proposed) bakes the ix86 axis into the metakit_punk port from day one (dual-arch
tests + mk4-format x64-writer/ix86-reader interchange check) - the 8.6 kit-side
consumer of this goal's runtimes once G-101 decides the container.

5
goals/G-131-boot-payload-autodetection.md

@ -78,6 +78,11 @@ independently-written branches.
goal costed at ~23 `Tcl_Size` call sites plus one `Tcl_ChannelType` and five
`Tcl_ObjType` initialisers. This goal runs ALONGSIDE G-101's decision - it does not wait
on it to be designed - but it cannot complete before that port work.
- 2026-08-02: G-153 (proposed) is where that port work starts - the fork-as-upstream
metakit_punk repo builds the storage engine + Mk4tcl under the pinned zig for the
8.6 side (dll + static-embed shapes, win32-x86_64 + win32-ix86). The Tcl 9 mk4tcl
port stays future work at the G-101-surveyed cost; G-153 only keeps the binding's
version-sensitive spots localized so this goal's 9-side arm stays bounded.
- Related: G-031 - the thin-main/shared-boot-core restructure. Container detection belongs
in the boot core, not in a per-project main; whichever lands second adopts the other's
shape. `project_main.tcl` carries the same code as `punk_main.tcl` today, which is why

136
goals/G-153-metakit-punk-zig-port.md

@ -0,0 +1,136 @@
# G-153 metakit_punk zig port: fork-as-upstream Mk4tcl for the 8.6 kit container
Status: proposed
Scope: external fork repo c:/repo/jn/metakit_punk (gitea jn/metakit - the port itself lands there); src/buildsuites/suite_tcl86/sources.config and src/buildsuites/suite_tcl86/build.zig.zon (ready-to-land metakit records drafted in the detail file; landing them is G-101-era consumption); TEMP_REFERENCE/{metakit_jnorthrup,metakit_pooryorick,KitCreator} (read-only patch/boot-chain reference - machine-local); goals/G-101-tcl86-kit-container-strategy.md (consumer decision record)
Goal: the punkshell-maintained metakit fork (c:/repo/jn/metakit_punk - gitea jn/metakit - pooryorick 2.4.9.8 porting baseline with the dead upstreams preserved as in-repo reference snapshots) builds standalone under the pinned zig toolchain as a Tcl-agnostic C++ core library plus the Mk4tcl binding in both loadable-dll and static-embed shapes, for win32-x86_64 and win32-ix86 alike, and a suite-built 8.6 shell loads and exercises the dll - so the G-101 mk4 container candidate rests on a first-party, commit-pinned, provenance-carrying source referenced by the buildsuites the punkzip way (gitea commit pin in sources.config plus zon tarball record) rather than on dead third-party upstreams or a wholesale vendor copy.
Acceptance: in c:/repo/jn/metakit_punk under the pinned zig 0.16.0, 'zig build' and 'zig build test' pass for both x86_64-windows and x86-windows with the 32-bit tests executed natively on the x64 host (WoW64); the KitCreator mk4tcl patch set (eight patches vs 2.4.9.7) is audited against the 2.4.9.8 baseline with a per-patch disposition recorded (ported as fork commits citing origin / already present in baseline / rejected with reason); the Mk4tcl binding builds as a stubs-linked dll against the same tcl core-8-6-branch pin suite_tcl86 carries and suite-built tclsh86t loads it - package require Mk4tcl plus an mk::file open/set/select/close round trip - with the transcript recorded in this file; an mk4 datafile written by the x86_64 build reads back identically under the ix86 build and vice versa; a static-embed shape (archive registerable via Tcl_StaticPackage) links into a copy of the kit-class shell target or its blocker is recorded here; the fork commit is pinned with ready-to-land sources.config and build.zig.zon record text captured in this file; and metakit_punk's root LICENSE lands with the first ported sources (MIT/X11 retained).
## Context
Metakit's upstreams are dead or dormant: the official jcw lineage froze at 2.4.9.7
(jnorthrup GitHub mirror, last commit 2011) and the pooryorick community fork at
2.4.9.8 (2018). The buildsuites' referencing pattern for LIVE upstreams (fossil
branch records in sources.config + per-checkin tarball pins in build.zig.zon,
suite-owned recipes over raw trees) therefore does not fit; the applicable
precedent is punkzip (G-126, achieved 2026-07-27 - see
goals/archive/G-126-punkzip-accelerator.md): a punkshell-maintained fork that IS
the upstream, self-hosted on gitea, commit-pinned by the suites, with its own zig
build system.
The fork repo was seeded 2026-07-30 (user-built skeleton): DOX/AGENTS.md
governance, read-only reference snapshots of both upstreams under src/reference/
with a provenance table, and a port-relevant fork-difference analysis (33 files
differ 2.4.9.7 -> 2.4.9.8; classified noise / warning-hygiene / type
modernization / Tcl-binding behavior). Its own contracts already fix key
decisions: port from the pooryorick snapshot only; Python binding out of scope;
upstream build systems (autoconf/MSVC/CMake) not carried; snapshots byte-frozen.
Direction confirmed by the user 2026-08-02: the port is driven from punkshell
sessions with access to this goals tree, so this file is the plan of record.
Boundary (deliberate, keeps the fork reusable): metakit_punk owns the storage
engine (upstream src/ + include/) and the mk::* Tcl binding (tcl/mk4tcl.cpp/.h +
tcl/tests). Kit boot machinery - kitInit.c preinit, boot.tcl, setupvfs-style kit
writers, rechan - stays G-101 suite-side territory (kbskit/KitCreator kitsh are
the references, per G-101's reading order), and mk4vfs.tcl ships with tclvfs
which the suite already builds. tequila/mkshow/mk4too stay reference-only unless
a need appears.
Sequencing value: milestones 1-2 (standalone build; dll smoke under tclsh86t)
need no shellspy changes at all, and the dll milestone doubles as G-101's cheap
first probe for the sdx bootstrap circularity (run sdx under the suite-built
dynamic shell with Mk4tcl loaded as a package - option (a) in G-101's sdx
section) and as the proof that a zig-built Mk4tcl works at all.
## Approach
- Target axis from day one: build.zig uses b.standardTargetOptions like punkzip
and build86.zig; test steps run for x86_64-windows AND x86-windows (WoW64
executes 32-bit natively on the x64 host - force the run steps if the builder
classifies the target foreign). Resolved triples map to punk canonical names
(x86-windows-gnu -> win32-ix86) for any artifact naming.
- Tcl headers without losing standalone buildability: a -Dtcl-src=<path> build
option whose default is a lazy build.zig.zon dependency on the SAME tcl
core-8-6-branch tarball pin suite_tcl86 carries (checkout 1d1d5cbd91), so
source identity matches the suite and a bare clone still builds with no
punkshell present. The dll shape links tclstub86; the static shape compiles
for Tcl_StaticPackage registration.
- Suite consumption shape (when G-101 lands it): unlike tcl/thread/tclvfs (raw
trees + suite-authored recipes), metakit_punk brings its own build.zig - the
suite consumes it as a zig package dependency (b.dependency().artifact())
rather than growing a forked build_mk4tcl86 recipe. Expose installed headers +
named static libs cleanly for that.
- Referencing is pin-only: no wholesale vendor of the fork into shellspy while
the port churns. If a make.tcl-level tool step later needs to rebuild metakit
from a bare shellspy checkout, the punkzip vendoring pattern
(src/tools/<name>/ + PROVENANCE.md, edit-upstream-first, re-vendor procedure,
G-063-style licence records) transfers directly.
- Restraint rules from the fork's own docs carry extra force during the port:
never re-simplify the pooryorick paren/brace hygiene; prefer per-file warning
flags in build.zig over source edits so diffs against the reference snapshot
stay meaningful.
- Early C++ spike before porting all ~47 files: link a trivial C++ static lib
into a copy of the kit-class shell target at both arches (zig's libc++ is
static on windows-gnu targets - measured 2026-08-02, no new dll imports beyond
the UCRT set the shells already carry, recorded in G-130 Notes) and check
whether metakit's THROW layer permits -fno-exceptions, which simplifies the
i386 EH story.
## Notes
- Related: G-101 (proposed) - the primary consumer: this goal is its mk4
candidate's leadup, separately landable; the container decision, boot chain,
sdx provenance/circularity, and the metakit-under-Tcl-9 port-cost survey all
live there. G-101 flags "deciding which patch lineage to carry is a required
step" - this goal's patch audit IS that step, landing as fork commits.
- Related: G-131 (proposed) - the strongest argument for the mk4 candidate is
one container format across both generations; G-131's metakit arm cannot
complete before the port work this goal starts. The 8.6-side shapes land
here; the Tcl 9 mk4tcl port stays future work at the cost G-101 surveyed
(~23 Tcl_Size call sites, one Tcl_ChannelType, five Tcl_ObjType
initialisers) - keep version-sensitive spots localized as they are touched,
do not port to 9 under this goal.
- Related: G-130 (proposed) - the win32-ix86 axis is baked into this goal's
acceptance (dual-arch tests + mk4 interchange check) so the fork never grows
an x64-only assumption; G-130 owns the 32-bit runtimes themselves. The
interchange check matters because punkshell's cross-baking path writes kits
on the x64 host for ix86 runtimes (the G-127 target-keyed bake lineage -
achieved 2026-07-31, see goals/archive/G-127-crosstarget-vfs-bake.md).
- Related: G-105 (proposed) - platform-name canon and the zig-triple <->
platform-dir mapping this goal's artifact naming follows.
- Related: G-026 (proposed) and G-063 (proposed) - fork-boundary provenance and
per-package licence records; metakit is MIT/X11 (license.terms retained in
the snapshots and in ported sources; root LICENSE lands with first port).
- Patch-audit inventory (from G-101's reference survey, KitCreator/mk4tcl/
patches/all/ vs metakit 2.4.9.7): 64-bit filespace, 32/64 fix,
unregisterchans, fixeventchannels, shared-obj linker, ranlib/ar (eight files
total). The pooryorick 2.4.9.8 baseline already absorbed at least the channel
unregistration and stdint fixed-width types (per the fork-difference analysis
in metakit_punk src/reference/AGENTS.md); the 64-bit filespace and
fixeventchannels lineage are the likely live ones. Audit each; x86_64
correctness hinges on the 64-bit set, and the linker/ranlib ones are expected
autoconf-era rejects.
- Draft sources.config record for suite_tcl86 (name/dir chosen to match the
gitea repo name; dir names are recipe-coupled per that file's header):
`source metakit git https://www.gitea1.intx.com.au/jn/metakit <commit> metakit`
(commit pin like punkzip - the fork carries no tags yet; the ssh origin
ssh://git@pcm-gitea1.corp.intx.com.au:2222/jn/metakit is the push remote, the
https web URL is the fetch/pin form).
- Draft build.zig.zon record for suite_tcl86 (hash computed with the pinned zig
at landing time - 'zig fetch' from the suite dir per that file's TRAP note):
`.metakit = .{ .url = "https://www.gitea1.intx.com.au/jn/metakit/archive/<commit>.tar.gz", .hash = "<zig-fetch>", .lazy = true },`
- UCRT/deployment: adding the C++ engine to shells changes exe size, not the
redistribution story - zig links libc++ statically on windows-gnu and the CRT
import surface stays the UCRT set measured in G-130 Notes (2026-08-02).
- 32-bit specifics: metakit's native era was 32-bit, so risk direction is
benign; mmap address space caps very large datafiles on ix86 (irrelevant at
kit scale - worth one doc line in the fork); the mk4 FILE FORMAT is
portable across arches by design, which is exactly what the interchange
acceptance pins.
- Version/package identity: keep `package provide Mk4tcl` at an upstream-shaped
version initially (2.4.9.8-era) for boot-script compatibility; fork releases
take their own repo-level versioning like punkzip did (v2.x.y). Decide the
exact package-version policy at first dll landing and record it here.
- Overlap survey 2026-08-02: goals_xref paths src/buildsuites/suite_tcl86,
src/buildsuites, bin/runtime/win32-ix86 -> G-101 G-131 G-105 G-130 (all
named above); suite_tcl90-side neighbours G-108/G-110/G-116 are
target/debug/tls lanes with no metakit coupling beyond shared suite dirs.
Loading…
Cancel
Save