A third-party 8.6 kit under evaluation (Lean Undroidwish Construction Kit, 32-bit windows)
could not load its own bundled twapi 4.7.2 inside punkshell:
P% package require twapi
invalid command name "twapi::set_scriptdir"
("package ifneeded twapi 4.7.2" script)
twapi's pkgIndex.tcl defines 'namespace eval twapi { proc set_scriptdir ... }' when the
INDEX is sourced, and its ifneeded script calls that command at require time. The command
existed - as ::punk::libunknown::twapi::set_scriptdir. punk::libunknown 0.2.0 moved index
sourcing out of 'namespace eval ::' into source_pkgindex, a proc of the punk::libunknown
namespace, to stop each index's helper variables leaking into the global namespace and to
stop a user global named 'dir' being clobbered. That fixed the frame, but a proc body
executes in ITS OWN namespace, so an index's RELATIVE 'namespace eval foo' started
creating ::punk::libunknown::foo instead of ::foo. Stock tclPkgUnknown is a proc in ::,
so indexes have always had global resolution; the ifneeded script, evaluated later at
global scope, then looked for a command that was never there.
The body now runs via apply with :: as its namespace argument, which gives both
properties at once: a local frame (index helper variables still discarded, user 'dir'
still safe) and the global resolution context indexes are written against.
Not twapi-specific: any index that defines commands or namespaces at source time for its
own ifneeded scripts to use hits this, and the pattern is common in third-party indexes.
punkshell's own vendored twapi 5.0b1 happens to avoid it (self-contained 'apply' ifneeded
scripts), which is why the tree never surfaced it.
Verified on the LUCK 8.6.10 runtime end-to-end - 'package require twapi' at the punkshell
prompt now returns 4.7.2 with ::twapi::scriptdir correctly set - and pinned generically by
pkgindex_relative_namespace_is_global in the discovery suite, whose new fixture copies
twapi's pattern so no third-party kit is needed. The pin was proven to bite: driven
against the pre-fix body the same fixture fails with 'invalid command name' and leaves
::punk::libunknown::pklu_nsindex behind; against 0.2.3 it resolves and leaves nothing.
Full suite 1165 tests, 1144 passed, 1 failure - core/tcl exec-14.3, the documented
baseline.
Manual-version bump per src/modules/AGENTS.md: file renamed, Meta line, manpage_begin and
provide-block updated, version-history line appended. The rename sweep converted the two
goal Scope references (G-035, G-109) from the exact filename to the glob form
src/modules/punk/libunknown-*.tm that GOALS.md's own Scope-authoring guidance recommends,
so the reference stops drifting at every bump.
Also records in G-035 the mechanism behind its "avoid mixing .tm and pkgIndex.tcl
provision" folklore, which this investigation identified (non-contract Notes). Stock
::tcl:™️:UnknownHandler returns early when $satisfied is set and therefore never falls
through to ::tclPkgUnknown, so a require satisfied from a .tm suppresses the whole library
scan. Measured with a synthetic fixture on both 8.6.10 and 9.0.3: with mixpkg 1.0 as a .tm
and mixpkg 2.0 in an auto_path library under 'package prefer latest', stock returns 1.0
and reports only 1.0 from 'package versions', runs no index side effect and registers no
sibling package; the libunknown chain returns 2.0 and does all three. libunknown already
neutralises it - its handler still computes $satisfied but the early return is commented
out - and that unconditional fallthrough is exactly what the epoch cache pays for. The
folklore is therefore substantiated for stock Tcl with a named failure mode (silent
older-version selection) and neutralised under the punkshell chain, with stock behaviour
still reachable in any interp that has not run punk::libunknown::init.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
The kit machinery already knew when it had failed to extract anything from a source
runtime, and under G-122 that notice became a recapped BUILD-WARNING - but the build
still assembled an artifact, DELETED the deployed kit and copied the new one over it,
closing running instances of the kit first. Field-observed 2026-07-26: an msys2-hosted
bake of punk91 produced a 49,501,792-byte bin/punk91.exe that failed at startup with
"application-specific initialization failed: Cannot find a usable init.tcl", by which
point the previously working kit was already gone. G-124 removed the particular cause;
this removes the class. A build tool should not make a working executable worse.
A bake now refuses any kit whose merged .vfs supplies no tcl library: the kit is listed
under FAILED KITS with a reason naming the cause and NOTHING is written - no
src/_build/<kit>, no deploy, and the previously deployed bin/<kit> is left byte-identical.
The gate sits immediately after the _vfscommon.vfs + <kit>.vfs merges and before the
kit-type assembly switch, the last point at which no build product exists; a refusal
appends to failed_kits, ends the punkcheck event FAILED and continues, so the punkcheck
records stay consistent with what is on disk. The merged src/_build/<kit>.vfs tree is
deliberately left behind - it is the evidence for the refusal.
It gates on the BOOT PRECONDITION, not on the extraction step having run. Some .vfs
folders legitimately supply their own tcl library (src/vfs/punk8_statictwapi.vfs,
punk9test.vfs and mkzipfix.vfs do today), and those must keep building - so the check
reads the merged tree. It is structural and executes nothing, which also makes it valid
for cross-target kits this host could never run, and costs 0.63ms per kit (measured over
200 iterations against the real src/_build/punk905.exe.vfs), so it runs unconditionally.
The predicate is punkboot::utils::vfs_boot_library_report (0.2.0 -> 0.3.0), called through
a guarded require modelled on the existing get_src_provenance_warnings: a stale or missing
bootsupport snapshot degrades the gate to a NOTE rather than failing every kit. Both
branches were observed live - before the bootsupport propagation 'make.tcl check' reported
UNAVAILABLE, after it ACTIVE. Scope was extended at activation (user-approved) to put the
predicate in that module rather than private to the build script, because a gate that
cannot be exercised cannot be characterized, and punkboot::utils is already where
make.tcl's provenance gate helper lives.
What qualifies as a tcl library: tcl_library/init.tcl (zipfs-attached kits) or
lib/tcl<major>.<minor>/init.tcl (starkit-style), AND at least one companion file beside it
(tm.tcl, package.tcl, auto.tcl, clock.tcl, history.tcl, word.tcl) or an encoding/
directory. The companion test is load-bearing: every punkshell kit carries
lib/BWidget1.10.1/init.tcl, so a check that looked for any init.tcl anywhere would pass a
kit with no tcl library at all. lib/tcllib2.0 is correctly not matched by the lib/tcl[0-9]*
glob. Verified against all 10 assembled trees in src/_build - both conventions are
represented (tcl_library for punk902z/punk905/punk91/punk9_beta/punk9bi_beta/punkmagic,
lib/tcl8.6 for punk86/punkbi/punksys, lib/tcl9.0 for punkshell902).
The no-extraction BUILD-WARNING was reworded from "will not initialise unless src/vfs/<x>
supplies one" - a consequence the build then ignored - to "will FAIL the boot-precondition
gate unless src/vfs/<x> supplies one". It stays a warning rather than becoming the failure,
because a .vfs that supplies its own library needs no extraction.
Verified 2026-07-27 end-to-end against a temporary fixture kit (a mapvfs entry pointing a
zip kit at a payload-free runtime, plus a vfs with no tcl library), with sentinel files
standing in for a previously deployed kit and a previous build product. Across the failing
run bin/punkgatefixture.exe (sha1 2a0700eb...) and src/_build/punkgatefixture.exe (sha1
12c50567...) were byte-identical with unchanged mtimes, and the kit was reported under
FAILED KITS with the cause named. Adding tcl_library/{init.tcl,tm.tcl} to that same fixture
vfs - extraction still yielding nothing - made it build and deploy normally, which is the
other half of the criterion. The fixture was removed afterwards and mapvfs.config restored
byte-identical to its backup. Real-kit bake through the gate: punk905 builds, deploys and
boots.
Characterization: 12 tests in modules/punkboot/utils/testsuites/utils/bootlibrary.test
(both conventions, the companion-file requirement and its BWidget decoy, near-miss
reporting, missing/empty trees, and a sweep asserting every assembled src/_build/*.vfs
tree still passes so the gate cannot fail kits that boot today) and 2 in
shell/testsuites/punkexe/maketclbootgate.test (the ACTIVE/UNAVAILABLE report, ESC-free per
the G-113 piped policy). Existing punkexe suites pass unchanged.
Documented in src/AGENTS.md with the remedy when a kit is refused, in ARCHITECTURE.md
beside the provenance gates, and in the embedded 'make.tcl workflow' data flow as key note
K10 (verified under the default and PUNKBOOT_PLAIN=1 paths, within the 100-column budget).
The achieved flip archives the entry and the detail file, and sweeps the live tier: G-127
(its output location inherits the never-written guarantee as long as the gate stays
upstream of the artifact write, and its payload/target mismatch reporting should share this
vocabulary), G-028 (the sibling "why bin/<kit> was not updated" surface in the same deploy
step) and G-101 (a new container type must land its library where the gate looks, or extend
the location list).
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
punk::zip could write a zip and split an executable-prefixed one, but nothing in the tree
could READ a zip without zipfs, vfs::zip or tcllib's zipfile::decode - a system package
punkshell does not vendor, with exactly one consumer: make.tcl's zipfs-less kit
extraction. Measured at drafting: msys2's /usr/bin/tclsh8.6 has no tcllib, so a bake
driven from that host could not lift the runtime's own zip (its tcl_library) into the kit
and the artifact did not boot.
punk::zip 0.1.1 -> 0.2.0 adds three commands, stock Tcl only. archive_info reports where
the archive begins inside its host file and which offset convention it uses; members
walks the central directory and returns one dict per entry without decompressing
anything; unzip extracts all or part of it with every member's crc32 verified,
directories materialized, and the writer's 2MB whole-member-vs-streaming threshold
mirrored. All three accept a plain .zip or a zip attached to an executable or script
prefix, so "what is inside this kit / runtime / modpod" is now answerable on a runtime
without zipfs.
The offset derivation is stated once and shared: offsetbase = cdiroffset - diroffset.
Positive means an external preamble with archive-relative offsets, zero means the offsets
are file-relative (or there is no preamble); dataoffset is the split point either way.
Because every surface reads the ORIGINAL file at that base, the file-relative shape stops
being a special case - the broken split-off intermediate is never produced.
tclsh90b4_piperepl.exe is the store's one file-relative artifact: the old
split-then-tcllib path still fails on it with exactly "Bad zip file. Bad closure.", and
it now extracts all 841 members crc-verified in 735ms.
extract_preamble consumes that machinery instead of carrying its own scan, and two
defects went with the refactor: it read 28 bytes of a 30-byte local file header, and it
derived the file-relative base from the FIRST central directory record only (its own
'#todo! loop through all cdr file headers'). The shared walk takes the minimum over ALL
records and then validates that a PK\3\4 really sits there. Its five puts stdout debug
lines are gone.
Refusals are decided for every selected member before any file is opened, so an
unsupported archive cannot leave a half-populated directory: encrypted entries, zip64
size/offset fields, unknown compression methods, crc mismatch (partial file removed) and
member paths that would escape the target are each named. Store and deflate only,
mirroring the writer's own primitives.
make.tcl's zipfs-less extraction now calls punk::zip::unzip on the original runtime and no
longer creates the extracted_<runtime>.zip intermediate. No punkshell code requires
zipfile::decode any more. Two categories of hit remain and are deliberate: tcllib's own
zip/decode.tcl shipped as a LIBRARY inside some .vfs payloads, and one guarded optional
probe inside the vendored third-party ooxml1.10/ooxml.tcl.
First tests punk::zip has ever had (src/tests/modules/punk/zip/), covering the three
archive shapes from one source tree, the introspection output, the named refusals, and
the mkzip -> read round trip - the first coverage that what punkshell WRITES is readable.
Verification, all 2026-07-26. Reference host for the dependency-free claim: msys2
tclsh8.6 8.6.12, probed as zipfs / vfs::zip / zipfile::decode all ABSENT - suite driven
there harness-free, 28 passed, 2 skipped (the zipfs-gated cross-checks only), 0 failed.
30/30 under Tcl 9.0.3, 28 + 2 skipped under native 8.6. Full source-tree suite after the
change: 1142 tests, 1 failure - core/tcl exec-14.3, the documented baseline. Independent
cross-check: 868 members of tclsh905.exe extracted byte-identical against the same
archive mounted with tcl zipfs. Bake demonstration: 'bake -confirm 0 punk905' driven by
the msys2 tclsh8.6 (host=msys-x86_64, target=win32-x86_64) produced
extracted_tclsh905.exe/{tcl_library,lib} with no intermediate .zip, and the deployed kit
boots with tcl_library at //zipfs:/app/tcl_library, 95 encodings, msgcat 1.7.1, http
2.10.2 - and reads itself with the new reader.
Trap worth keeping: zlib stream inflate's 'get' returns only what the stream has already
produced, so one get per put silently truncates a large member to the first few chunks
(measured 327680 of 5048890 bytes on both 8.6.12 and 9.0.3). The inner drain loop is
load-bearing, and the >2MB streaming test exists to catch its removal.
Standing question answered and pinned: zipfs does NOT misidentify punk::zip::mkzip
directories. It keys on the trailing slash (which punk::zip::walk always emits), not the
stored permission bits, exactly as the current cli-999999.0a1.0.tm wording says - the
older, less precise wording survives only in frozen module snapshots under
src/vfs/mkzipfix.vfs and src/vfs/project.vfs. The real difference from zipfs mkzip is
that zipfs writes no directory entries at all.
The achieved flip archives the entry and the detail file, and sweeps the live tier: G-034
(the reader is its extract-rather-than-mount alternative, plus the measured finding that
make.tcl on 8.6 cannot mount its own templates modpod), G-101 (the read half of a
zipfs-less 8.6 container is solved), G-125 (the gate now has a named failure reason to
report), G-126 (the member-dict keys and fixture set its parity suite must reproduce, and
a back-pointer to G-128 whose only recorded bridge was this goal), G-128 (archive_info
answers "is this artifact safe to move the overlay of?" in one call).
One acceptance clause is reported for review rather than claimed silently: "NO
zipfile::decode requirement remains anywhere in the shipped tree" is satisfied for
punkshell's own code, with the vendored-third-party residue named above.
The archived detail file's diff is a rename plus the flip's evidence write-up.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Follow-on goals from the G-122 host/target split, each drafted with its overlap survey
and approved before writing. The G-057 contract edit (title, Scope, Goal, Acceptance) was
shown clause-by-clause and approved per the proposal-first rule.
G-057 amended - the goal was drafted before G-122 separated host from target, so its skip
condition read as one host-shaped test ("non-Windows platform skips") while its Notes used
target language. Split in two: a target with no PE resources is NOT APPLICABLE, a windows
target on a host that cannot run twapi is a distinct shortcoming. Both still emit a text
sidecar, now produced for every kit on every target and defined so the parked RT_VERSION
follow-on extends the same file rather than adding a second. Embedding sits behind a
single mechanism seam, and the twapi arm is explicitly PERMANENT - the seam selects
between mechanisms, it does not replace one: twapi is vendored and git-tracked
(src/vendorlib_tcl8|9/win32-x86_64/twapi-5.0b1) and reachable from make.tcl's auto_path,
so a fresh windows checkout that fetches a runtime and bakes gets icons with no build
toolchain (probed under a stock tclsh 9.0.3 and a fetched plain family runtime). The
per-vfs override is settled as shared across a kit definition's targets with no target
dimension.
G-127 - cross-target bake of a custom .vfs. G-122 made the build READ the right runtime
for a target; this makes it WRITE the right kit for one. Three measured gaps: output is
flat, so two POSIX targets of one kit collide (within a run the duplicate guard renames by
RUNTIME not platform; across selective runs exe_names_seen resets and the second
overwrites the first); the payload model is one hand-curated folder per target
(punk9linux.vfs, not a vfslibs participant, with vendorlib_vfs.toml hardcoding the
platform into its source path - a shape inherited from G-037 when there was one target);
and nothing verifies payload against target. Non-native kits go to bin/kits/<platform>/
with native staying at bin/<name>; /bin/* already ignores it so no dual-track ignore work.
Records that G-114 and G-115 overlap yet never reference each other - the platform axis
and the payload axis have never been connected.
G-128 - portable PE resource stamping via a vendored zig tool, plugging into G-057's seam
without retiring its twapi arm. Feasibility measured: zig rc (resinator, bundled in the
0.16 toolchain) is a resource COMPILER supplying the RT_GROUP_ICON/RT_ICON structure
reference, not a patcher - we never link these runtimes, so patching an existing PE is the
work. In our runtimes .rsrc is not the last section (.reloc follows), so the
implementation appends a section and repoints the resource data directory, which shifts
the overlay: safe for an archive-relative zip, not for a file-relative one, so the unsafe
case is refused rather than corrupted. The payoff beyond portability is post-hoc stamping
of a finished kit, which removes G-057's icon-before-append ordering constraint. Its
distribution is settled as buildable from vendored source AND publishable as a punkbin
artifact, so the no-toolchain route need not depend on the committed twapi (the G-004
tension).
Also adds non-contract Related back-pointers in G-057 to G-122/G-127/G-128.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Three goals arising from the G-122 work, each drafted with its overlap survey and
approved before writing.
G-124 - dependency-free zip reading in punk::zip. Nothing in the tree can READ a zip
without zipfs, vfs::zip or tcllib's zipfile::decode, which is a system package punkshell
does not vendor and which has exactly one consumer: make.tcl's zipfs-less kit extraction.
The goal removes that requirement outright (not as an optional fallback), adds an
introspection surface so punk::zip is useful to script programmers, and gives the writer
its first round-trip coverage. Measured motivation recorded in the detail file: msys2's
tclsh8.6 has no tcllib and so bakes an unbootable kit, and extract_preamble's live
'#todo - need to adjust offsets' means a FILE-relative prefixed executable
(tclsh90b4_piperepl.exe) splits into a .zip tcllib rejects with "Bad closure" - reading
the original file at its derived base offset removes that failure mode by construction.
G-125 - a kit that cannot boot is not deployed. Today a failed extraction emits a
recapped BUILD-WARNING and then deletes and replaces the deployed kit anyway; field-
observed 2026-07-26 replacing a working punk91.exe with one that dies on init.tcl. The
gate tests the boot precondition on the assembled vfs, so a kit whose payload legitimately
supplies its own tcl library still builds.
G-126 - punkzip as a VENDORED zip accelerator behind G-124's pure-Tcl floor, with zig
kept optional (a tclsh-only clean checkout must still build and bake). Feasibility
measured and recorded: the source builds clean under its declared zig 0.15.2, and under
0.16 fails on one surfaced error (std.process.argsAlloc), with the OS-facing surface
confined to 3 of ~20 files while the ~10k-line compression core is untouched; zig 0.16.0
is already unpacked in bin/tools. Benchmarks captured for the speedup claim.
Non-contract Notes back-pointers added to G-034 (the reader is a candidate for its own
Acceptance's "alternative modpod mount path" branch) and G-101 (an 8.6 container has no
zipfs, so it needs a reader that works without one).
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Everything a bake EMITS is now keyed by the artifact's TARGET platform rather than the
driving tclsh's personality: the bin/runtime/<tier> store a runtime is read from, .exe
suffixing of runtime files and kit outputs, presence checks, 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 platform canon EXCEPT for a cygwin-family host (an
msys2/cygwin-runtime tclsh, which reports tcl_platform(platform) unix on windows), which
targets win32-x86_64. Such a host now drives the identical kit set, names and store
addressing as a native tclsh; before, it reported every kit runtime=missing against a
nonexistent mingw64-x86_64 store.
mapvfs.config entries take an optional 4th element naming the kit's target platform, so a
runtime kept in another platform's tier is a first-class mapping entry. The linux tclkit
entry now declares linux-x86_64 and bakes to a suffixless bin/punkshell902.
Zip-type kits assemble without zipfs in the driving tcl: when tcl::zipfs::mkimg is absent
(any 8.6) the image is built by raw-runtime split + punk::zip::mkzip + concatenation - the
same helper the zipcat type uses. Both mount identically (archive-start-relative offsets).
Fixes exposed by the above: the runtime capability probe looked for a suffixless filename
and so reported find-fail for every runtime on windows; with real capabilities arriving,
the extraction try-list was found to test capability presence rather than value, which
would send a plain zipfs runtime down the kit path where a failed sdx mksplit replaces
raw_runtime with the un-split original; BUILDCOPY names now follow the runtime's own
filename; runtime map keys strip only .exe (file rootname would eat the last dotted
segment of tclsh9.0.5); and native windows command lines run through a guard suppressing
msys2's posix-path argument rewriting - without it taskkill /PID <n> reached taskkill as
taskkill C:/<msysroot>/PID <n>, so the sweep could find a running kit but never replace it.
punk::platform folds the msys2 family (mingw64/mingw32/ucrt64/clang*) onto one stable
'msys' tag and CYGWIN_NT onto 'cygwin' - msys2's uname renders that token from MSYSTEM,
so one binary otherwise canonizes differently per launching shell. New normalize_os;
cygwin-x86_64 added to the platform table; 'help platforms' documents the fold.
make.tcl check reports the derivation on one line; bakelist rows carry target=<platform>
for non-default targets and the detail block names the tier; workflow text gains key note
[K9]. New characterization suite maketclplatform.test (5 tests, two self-gating on
discovering and probing a real msys/cygwin tclsh). Full suite 1112 tests: 1093 passed,
18 skipped, 1 failed = the documented exec-14.3 baseline.
Verified: msys2 tclsh8.6 bakelist output identical to native Tcl 9; a changed punk91
baked and deployed from that host with the sweep killing a running instance msys ps
cannot see; a real cross-target linux kit baked from windows to a 24MB ELF; a zipfs-less
8.6 bake producing a bootable zip kit.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
The pre-activation survey (f4031b20) extended G-101's Scope in the detail file
but not the index, leaving goals_lint at exit 1 on the Status/Scope mirror
check. Scope is a contract element canonical in the INDEX, so the detail-file
edit was both the wrong tier and not proposal-first - that commit's "Notes-only
on the goal" opening misclassified it. A clean lint run would not have caught
the underlying problem either: had both tiers been edited together lint would
have passed green with the contract change still unapproved. goals_lint checks
consistency, not authorization.
User-approved this session: the index moves to the extended wording rather than
the detail file reverting - the survey genuinely brought bin/sdx.kit and three
further reference trees into the goal's territory.
Both tiers now carry an identical, tier-neutral line. The survey's "see ...
below" cross-references resolve only inside the detail file while the index
entry must stay safe standalone (GOALS.md Format), so they become "inventory in
the detail file". src/buildsuites/suite_tcl86/patches/ is added: the sdx
wrap.tcl provenance capture is tracked material this goal now owns and was named
in neither tier.
goals_lint clean (79 active-index goals, 44 archived).
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Extends the 8.6 buildsuite with the remaining pieces punkshell's Tcl 8 testing
depends on, all built from source with the pinned zig 0.16.0 toolchain only.
Tk 8.6.17 (build_tk86/build_tk86.zig) is a RE-DERIVATION from the staged 8.6
win/makefile.vc + rules.vc, not a port of suite_tcl90's build_tk.zig:
- no generic/tkPkgConfig.c in 8.6 -> no CFG_* defines at all
- rules.vc TCL_MAJOR_VERSION==8 arm -> tk86t.dll + lib/tk8.6 (vs tcl9tk90.dll)
- @TK_WIN_VERSION@ substitutes $(DOTVERSION).0.0, not the tcl-style
<dotversion>.<releaselevel>.<patchlevel> formula
- 8.6 TKOBJS carries no tkIcu/tkImgListFormat/tkImgSVGnano/tkWinGDI/tkWinIco/
tkWinSysTray; XLIBOBJS is a first-class makefile macro here (the 9.0
derivation had to recover those files by hand)
USE_TCL_STUBS + USE_TCLOO_STUBS against libtclstub86.a is the stock rules.vc
arrangement and keeps the dll loadable by both suite shells. tkMain.c is
compiled twice per makefile.vc, the ansi copy forced with -UUNICODE/-U_UNICODE
(verified the pinned zig cc defines neither for x86_64-windows-gnu, so the 8.6
core's ANSI/TCHAR arrangement is matched exactly).
tklib 0.9 and tcllib 2.0 install via their own installer.tcl (batch, packages
only, explicit -pkg-path so the installer's tcl_pkgPath-derived default can
never write off-tree); tcllibc is built by critcl 3.3.1 driving zig cc (tracked
critcl_zig.config, target pinned win32-x86_64-zig - critcl otherwise probes PATH
and falls back to its builtin msvc target). critcl compiles against its own
bundled headers chosen by the driving shell's version, which is why one config
serves both generations.
New evidence tools, run on every build:
tools/tk_smoke.tcl maps a real toplevel with classic + themed widgets,
updates, then destroys it - a load-only check passes
even with no usable display
tools/accel_bench.tcl same payload through sha1's critcl and pure-Tcl
implementations with the digests compared:
4MB -> critcl 5.7ms vs pure-tcl 2736ms = 477x
Test tiers (G-107 policy pattern): test-tcllib/test-tklib on the record tier
inside test-libraries, plus an opt-in test-tk (winDialog/winMsgbox excluded by
default - their message-injection automation blocks on a human under a batch
shell). First censuses on tclsh86ts.exe 8.6.18:
thread 142 run / 0 failed GATE PASS
tklib 796 run / 0 failed record
tcllib 64259 run / 41 failed record (names in the summary artifact)
tclvfs 51 run / 4 failed GATE PASS after baseline extension
The tclvfs baseline grew vfsFtp-1.1..1.3: they sit behind an 'ftp' constraint
needing tcllib's ftp package - absent at the G-099 capture, satisfied now that
the suite installs tcllib - so they run and reach the retired ftp.tcl.tk, the
same external-service class already baselined for vfsUrl-1.2/2.1.
punkshell runtests census (both runs 2026-07-26, identical flags, default
single-process sequential - 8.6 has no tcl::process so -jobs re-convoys):
native Tcl 8.6.17 1003 total / 986 passed / 10 skipped / 7 failed
suite tclsh86ts 1003 total / 987 passed / 10 skipped / 6 failed
runtests_parity.tcl finds exactly ONE difference: punkcheck
concurrency_two_writers_no_corruption failed in the BASELINE run and passed on
the suite runtime - a full-suite-load flake (6/6 twice in isolation on both
runtimes). Zero suite-runtime-only failures. Tk-dependent suites ran unskipped
(repl consolebackends 3/3, including the tkconsole backend on the suite Tk).
Two defects fixed in passing:
- scrubTclEnv never cleared TCL<major>_<minor>_TM_PATH, so suite shells
silently preferred machine/repo tm modules over what the suite had just
installed (a repo-built sha1-2.0.4.tm shadowed tcllib's 2.0.5, md5 2.0.8
shadowed 2.0.9) - any census through such a shell measures the machine. The
scrub list now covers TCL8_0..8_7 + TCL9_0/9_1 in all three sites (per-step,
suite.tcl process-level, bootstrap nested build). suite_tcl90 has the same
exposure via TCL9_0_TM_PATH and is deliberately untouched here (out of this
goal's scope) - pointers recorded in G-108 and G-116.
- build.zig.zon's .fingerprint was hand-authored, so 'zig build' from the
tracked suite dir died with 'invalid fingerprint' - the no-tclsh bootstrap
flow could never have run. Corrected to zig's computed value (its low half
is a checksum of the package name); 'zig build stage' now verified.
Goal flipped to achieved 2026-07-26 and archived; reference sweep updated G-005,
G-101, G-105 and ARCHITECTURE.md, and the archive-time xref pair G-101 <-> G-116
(whose only bridges were the archived G-100/G-103) gained a direct Related
pointer. No project-version bump - arm's-length build tooling, not shipped shell
behaviour.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Builds a Tcl 8.6.18 windows runtime from core-8-6-branch sources with the
pinned zig 0.16.0 toolchain only (no MS toolchain), forked from suite_tcl90
(duplication-with-a-note posture). Products (stock threaded-release naming -
rules.vc keeps the 't' SUFX on 8.6):
bin/tcl86t.dll + tcl86t.lib shared core (static zlib compiled in; no zlib1.dll)
bin/tclsh86ts.exe static shell (kit-class; dde/registry static)
bin/tclsh86t.exe dynamic shell against the dll
lib/libtclstub86.a stub lib for extensions
lib/tcl8.6/... script library tree (dde/reg dlls inside)
lib/tcl8/{8.5,8.6}/... tm modules; lib/thread2.8.13, lib/vfs1.4.2
Companions: thread 2.8.13 (thread2813t.dll, TEA installed shape from the
checkout's own pkgIndex.tcl.in) and tclvfs 1.4.2 (vfs142t.dll) build and load;
registry 1.3.5 / dde 1.4.6. No zipfs in 8.6 - exe+dll+on-disk lib tree only,
resolved hermetically (exe/dll-relative, TCLLIBPATH/TCL_LIBRARY unset in all
child runs).
Recipe: build86.zig + build_common.zig + build_zlib86/build_tclthread86/
build_tclvfs86 helpers; tools/ and src/main.zig copied verbatim (suite-agnostic).
Two load-bearing 8.6 findings recorded in the README DERIVATION and recipe
comments: MP_FIXED_CUTOFFS (the in-core libtommath ships no bn_cutoffs.c) and
TCL_BROKEN_MAINARGS + console subsystem for the gcc-class main() entry.
Test gates (suite.tcl test -> zig build test-gate/test-libraries) parse all.tcl
totals (exit codes untrusted) and gate against tracked dispositioned baselines.
First census + two-consecutive-run deterministic PASS (machine SuperBee):
core 46525 run / 2 failed (filename-16.12/16.13 admin-share self-globbing)
thread 142 run / 0 failed (empty baseline)
tclvfs 51 run / 2 failed (vfsUrl-1.2/2.1 external ftp.tcl.tk dependency)
Goal flipped to achieved 2026-07-26 and archived; reference sweep updated G-005,
G-100 (now unblocked), G-101 and ARCHITECTURE.md. No project-version bump
(arm's-length build tooling, not shipped shell behaviour).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Index entry + detail file with the two user-directed amendments over the
presented draft: consent keyed to SERVER TRUST (trusted set defaults to the
canonical punkbin origin - no new prompts in existing flows incl. the
unattended tclsfe-x64 constraint fetch; untrusted/alternative servers gate
with a G-006-pattern acknowledgement surfacing the provenance class), and
retroactive schema-v2 provenance sidecars for the existing punkbin
third-party artifacts (additive only - bytes, bare pre-family names,
sha1sums.txt authority unchanged). Signing deliberately deferred per user
("down the track") with the minisign anticipation noted. Depends on G-122;
Related G-006/G-067/G-105/G-101; extends archived G-103/G-119 machinery under
a G-117 schema-v1 -> v2 bump. G-122's follow-on note now cites G-123 by id.
Claude-Session: https://claude.ai/code/session_01Jz7wkUsknJzyuJ3tgMaL2t
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full (evidence recorded in the detail file's Progress
section): bakelist under plain tclsh + punk902z with per-entry presence and
deployed state; selective 'bake punk91' refreshing only that kit's _build/bin
artifacts and punkcheck records (stat + punkcheck diffs, negative grep clean);
unknown-name no-build errors; bare bake kit-set parity; help/workflow contract
updates; maketclbakelist.test 4 PASS; punkshell 0.24.0 minor bump.
Index entry moved to GOALS-archive.md. Reference sweep: no pending-tense
live-tier mentions existed; mapvfs.config pointer updated to the archive path;
forward-pointing notes pushed as back-pointers to the live goals they serve
(G-024 parsed-model reader swap, G-023 scheme-expansion entry point, G-115
per-kit payload detail, G-057 single-kit icon verification, G-028 deployed
-state reporting sibling, G-101 kit-type non-assumption).
Detail-file move to goals/archive/ follows in the adjacent commit as a pure
rename (root AGENTS.md Doc Restructures).
Claude-Session: https://claude.ai/code/session_01Jz7wkUsknJzyuJ3tgMaL2t
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New proposed goal: 'bakelist ?kitname...?' informational lister (mapping +
runtime presence + deployed state; name filter doubles as per-kit detail) and
'bake ?kitname...?' selective baking with bare bake unchanged. Both defined
against the parsed mapping model so the G-024 toml conversion slides
underneath. Ergonomics decision record in Alternatives (bake -list and
action-grouped bake rejected per the G-112 stage-true principle; bare 'kits'
already rejected in the G-112 name-selection record). Overlap survey recorded:
substantive relations G-024/G-023/G-115/G-057/G-028/G-101 + archived
G-104/G-098 precedent. Delivers the mapvfs.config todo (comment retires when
the goal lands).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New informational pass in goals_lint (stem-sibling repair heuristic): a
live-tier reference to a version-suffixed filename that is MISSING while a
same-stem sibling exists on disk warns, naming the sibling(s) - the drift
signature of manually-versioned module bumps (libunknown), magic-scheme
conversions (config) and stamped bootsupport/vendored renames (fauxlink),
exactly the classes fixed in the preceding hygiene commit. References with no
stem-sibling stay quiet (proposed goals legitimately name future artifacts);
archive tier, globs, URLs, absolute paths and 999999.0a1.0 exempt; warnings
never fatal (Scope is contract text - the fix stays a directed edit).
Verified: clean on the current tree (incl. correctly-silent existing legacy
artifacts) and against a synthetic fixture exercising warn + all five silent
classes with per-file dedupe.
GOALS.md: front matter bumped v2 -> v3; version-section policy broadened per
user direction - bump for ANY change that could affect how an LLM interprets
or uses the system (contract, grammar, tooling behaviour, output shape);
liberal bumping endorsed. Format section gains Scope version-reference
guidance (glob or magic-version filename for stamped files; exact versions
only in dated prose). goals/AGENTS.md Verification describes the new check;
src/modules/AGENTS.md manual-versioning bullet gains bump step (4): the doc
reference sweep.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Activation gated on the G-112 rename core + G-104 contract (both achieved
today); score re-run recorded. First increment:
- suite_tcl86/: sources.config (source + self-description records - lists and
describes itself via 'make.tcl buildsuite list/info' with no make.tcl
edits), suite.tcl fork (folder-derived naming, {tcl tclthread tclvfs}
requireds, build86.zig recipe file), build86.zig pending-derivation skeleton
(staging succeeds, recipe fails with a clear message), build.zig.zon with
real zig-fetch hashes, README with the DERIVATION record.
- Thread 2.8 selection: thread-2-8-branch @ e14fa771ae (tagged thread-2-8-13,
2.8.13); configure.ac TCL_MAJOR_VERSION==8 guard confirms the pairing.
- 8.6 source records in BOTH flows: dev refs (core-8-6-branch -> tcl86,
thread-2-8-branch, tclvfs trunk 1.4.2-era) + zon per-checkin pins
(tcl 1d1d5cbd91 = 8.6.18 era).
- First staging run through 'make.tcl buildsuite build suite_tcl86' (a real
driver run through the G-104 surface): checkouts staged from the shared
hermetic store, TCL_PATCH_LEVEL 8.6.18 read from the tree.
- makefile.vc derivation findings recorded incl. two Context corrections:
8.6.18 DOES generate tclUuid.h; zlib is prebuilt-import in stock nmake
(zig-only recipe will compile compat/zlib statically).
Core-test census + baseline deliberately pending until a built tclsh86 exists
(recorded in Progress).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance evidence recorded in each detail file before the content-identical
archive moves:
- G-112: fresh-rebuild bake products BYTE-IDENTICAL to pre-rename vfs products
(punk91 zip-wrap + punk86 kit-wrap; vacuous punkcheck-skip pass caught and
redone), vfslibs phase runs inside bake, aliases + bakehouse dirty-refusal
verified live, docs/layout copies swept, punkexe suites 54/0 green.
- G-113: zero-ESC piped on tclsh90 + punk kit + 8.6, force overrides, real
Windows-console and WSL-pty mode=tty evidence, maketclcolour.test green;
manual-visual note recorded.
- G-104: list/info/build + self-description contract verified incl. a copied
tree; punk-kit hosting; docs in place.
Sweep: G-005/G-018/G-035/G-047/G-099 pending-tense references rewritten with
archive pointers; forward-notes pushed to G-108/G-061/G-105; G-099<->G-108
re-bridged with a direct Related line (their bridges were all archived).
Also: tclsh9.0.5-punk working runtime re-materialized to r2 (stale local
materialization exposed by the window's bake - G-118 piperepl pins green again).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Activation-freshness scores re-run per the maintenance rules and recorded in
each detail file's Notes; new Related lines: G-104 -> G-108 (debug-tier
variants ride the same driver/self-description contract), G-113 -> G-061
(ConPTY could automate the interactive-colour verification). G-112 open
decisions resolved at activation (user-directed): vfslibs folds into bake
(standalone-narrowing survival decided in-session), project/vfs alias
deprecation window = until the 8.6 arc completes.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified on the rebuilt punk91 kit (plain script mode): recipe
'chan close stderr; open NUL w' yields a channel auto-named stderr with
working puts stderr; console+repl+libunknown suites 105/105. Detail file
archived content-identically with evidence recorded; GOALS-archive record
appended; sweep: G-101 launch-ladder item (2) rewritten to reflect
achievement (in-place stdio repair now available on the 9.1 kit), G-011
gains a recycled-stderr consumer pointer. goals_xref report shows no
orphaned shared-archived-ref bridges for G-120; goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Activation: proposed->active flip (user-confirmed), goals_xref score re-run
recorded in detail Notes (nothing beyond the drafting survey).
Holder named: punk::libunknown zipfs_tm_UnknownHandler's builtin-static
shortcircuit leaked its version-probe child interp 'ptest' whenever an
UNVERSIONED package require of a true static reached the handler -
'package vsatisfies $v' with zero requirement args throws wrong#args,
skipping both interp-delete lines. The leaked non-safe child holds
registrations on the process std channels, so 'chan close stderr' left the
OS handle alive and the slot occupied; the next open got a fileN name and
puts stderr failed (punk91/tclsfe-9.1b0 only: Thread is a true static there,
punk905 loads it from a dll so the block never fires).
Fix (0.2.2): auto-named probe interp deleted in try/finally; zero-requirement
requires accept any provided static version; probe errors fall through to the
normal tm search. Disposition recorded in the goal detail: leak, fixed - not
console-ownership machinery.
Verified: bin/punk91 src script recipe yields channel auto-named stderr with
working puts stderr; libunknown+console+repl suites 105/105 pass (tclsh90).
punkproject 0.22.1 + CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full against the fixture punkbin server
(PUNKBIN_URL override): ahead/behind verdicts naming both revisions
(behind with fetch+use guidance), current annotation preserved,
pre-family no-basis note + sha1 hash-identity, no-name-fetch one-line
divergence note; ps1/bash verdict-line parity asserted per scenario;
runtimecmd roundtrip pin green; bin/AGENTS.md runtime-manager contract
records the surface. Suite evidence in the detail file's flip record.
Activation and flip both 2026-07-25 (user-directed activation; overlap
survey re-run at activation - only G-033 related, already recorded; no
new Related lines). Detail file: status achieved + activation/flip
evidence records (the goals/ -> goals/archive/ move itself rode the
previous commit as a pure 100% rename; this commit carries the flip's
content edits). Index entry moved to GOALS-archive.md. Reference sweep:
G-033's G-119 note updated to landed-state wording with the archive
path (its package-mode docs must not contradict the shipped freshness
contract on naming); goals_lint clean (83 active / 37 archived);
goals_xref report carries no G-119-bridged unlinked pairs.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full: all 11 issue-list items dispositioned
(2026-07-24) with decided fixes landed (items 3/4/5/9 in 0.20.0, items 1/7
via the G-117-cycle patch rev, item 10 docs in 0.20.1, item 11 console test)
and items 2/6/8 documented-as-intended in the item-10 definitions; durable
doc home = punk::args::moduledoc::punkexe; tclshcmd.test 19 piped tests
green vs punk902z + punk9_beta; dorepl console-reopen path console-driven
(punkconsole gate, 21/21 with PUNK_TEST_CONSOLE=1).
Flip: detail file status achieved 2026-07-25 + flip evidence record; entry
moved to GOALS-archive.md; detail file to goals/archive/. Reference sweep:
ARCHITECTURE.md tclsh bullet marked achieved + G-118 removed from the
in-flux launch-surface list; G-031/G-032/G-077/G-120 notes updated with
archive markers and landed-state wording (G-032 now points at the shipped
punkexe moduledoc ids as its source material; G-077 notes the boundary text
to update when -e lands). goals_lint clean, architecture_lint clean,
goals_xref report carries no G-118-bridged unlinked pairs.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- GOALS.md: "Goals-system: v2" front matter; canonical "Goals system versions"
section; Scope structure rule (elements separated by '; ' at top level,
commas only inside parens/braces); Child DOX Index note in root AGENTS.md
- goals_lint.tcl: new finding for top-level commas in Scope lines
(paren/brace depth-aware)
- goals_xref.tcl: repo-local configuration via goals/xref.conf (path roots,
stop words, file extensions, reference containers, module dirs,
bare_path_roots, prefix_anchors); defaults byte-identical to previous
behaviour (verified on this tree)
- goals/AGENTS.md: cross-repo goal references drop the G- prefix; xref.conf
documented in Verification
- Scope delimiter normalisation across GOALS.md, GOALS-archive.md and all
detail files, live and archived: 224 lines, top-level commas only;
conservation verified (goals_xref report byte-identical pre/post, diff
hunks are Scope lines only). Archived tier converted under explicit user
approval; sanctioned exception recorded in GOALS-archive.md.
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
Acceptance evidence in the archived detail file: embed verified in all three
family members (family_check), sidecar derived from embed with identical
build_id, 'info' identifies sidecar-paired/renamed-stray/pre-v1 files without
execution and flags doctored-sidecar disagreements, punkbin AGENTS.md schema
docs, roundtrip pin green, record survives make.tcl kit wrapping (punk9_beta
reads its runtime's r2 record in-kit), r2 re-emitted with full v1 records.
Sweep: achieved markers in G-025/G-057/G-108/G-116/G-118/G-119 (G-025's
survival expectation updated to confirmed). tclshcmd.test pins
::tclsh(reopened) publication on the rebuilt patched kits (G-118 items 1+7
landed+verified; Progress updated). build905.zig: packager git-identity leg
judges success by output not out_code (resolved 'unrecorded' on this host -
effective at next emission).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved draft from the publication-session design exchanges:
embed a copy of the artifact record in the attached image (embed-then-
hash ordering; sidecar + sha1sums stay the integrity authority) with a
punk-runtime 'info' action for stray/renamed binaries (zip-central-
directory read preferred over executing the target), AND harden the
record as schema v1: schema, build_id (embedded+sidecar correlation
uuid), origin (canonical repo built FOR - the timing-safe reframe of
first-published-on; mirrors preserve it), packager (declarative;
minisign noted as the verification complement), project/project_url,
license summary, build_host_platform. Emitted records gain brief toml
'#' comments for non-obvious fields (line-based consumers ignore them
by construction). Lifecycle fields deliberately rejected as repo-level
curation. Next emission after landing = r2; published r1 immutable.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved draft giving the tcltls battery line a live goal home after
G-103's archive: backend choice (LibreSSL-portable vs no-asm OpenSSL) is
an in-goal decision, static link mirrors the tcllibc/tk shape, loopback
self-signed handshake + G-107 record-mode testsuite as verification, and
vendored prebuilt removal explicitly scoped OUT (recorded disposition
only - G-004-era work).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Final acceptance item closed by the punk9_beta/punk9bi_beta kit-wrap
trial (user go-ahead; quiet tree): make.tcl project wrapped both kits
over the family runtimes (the user's own earlier same-day build agreed -
punkcheck no-change), and probes UNDER each kit verified 9.0.5,
//zipfs:/app/tcl_library, PIPEREPL MACHINERY PRESENT, Thread 3.0.7
winning over the vfs payload's legacy thread3.0.1, vfs/tcllib/tcllibc
engaged, punk::args from the vfs side, and Tk create/destroy in both -
punk9bi_beta's Tk necessarily from the runtime's attached image
(punk9win_for_tkruntime.vfs carries none). Every acceptance clause is
now met; evidence recorded in the detail file.
Flip mechanics: Status achieved 2026-07-22; detail file to
goals/archive/ (content-identical move after edits); index entry to
GOALS-archive.md; reference sweep across 13 live goal files (archive
markers per the G-058 precedent - non-contract text only, Scope lines
untouched; pending-tense updates in G-099 arc-unblocked, G-108 family
production landed, G-018/G-023 naming-authority pointers). Forward
pointers pushed to live goals: G-101 (8.6-family deferral target),
G-067 (family -rN artifacts exist; publication user-gated with the
defaults.txt flip process).
Flagged (completion report): tcltls bi-battery line loses its goal home
with this archive - candidate goal on request; punk9wintk905.vfs legacy
thread3.0.1 payload cleanup can ride a future payload refresh; beta
promotion is the user's interactive trial per the *_beta convention.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved draft from the binary-policy framing discussion: per-.vfs
toml declarations materialize payload from suite build products, punkbin
artifact classes (consent-gated) and vendor trees, making kit payloads
buildable on a clean binary-free tree (G-004) - while the folder remains
the operative assembly area: declarations optional, undeclared drop-ins
preserved (permissive derived projects and gitignored test .vfs keep
drop-in simplicity). Context records the precedents (vendorlib_vfs.toml,
G-087 layout_materialize, vendored tomlish), the relationship to the
punkbin third-class question, and precedence design as the core work.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved draft from the platform-canon survey discussion: binary
modpod .tm are one-platform-per-file under per-platform TM ROOTS the boot
registers for the running platform only (punk::platform canon names).
Context records the motivating fat-tm evidence (oversized downloads;
same-version shadowing with no drop-in path), the subdirs-are-namespace-
components constraint forcing sibling roots, and the division of labour
with G-109 (manifest target-platform field stays there). Deliberately
dormant until binary-.tm distribution starts - no speculative structure.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Content-identical detail-file move; the flip's content edits (Status,
evidence, recipe) landed in the previous commit per the doc-restructure
move/edit separation rule. Index entry relocated with Scope verbatim and
the detail file's Acceptance per the archive record format.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Next in the user-confirmed sequence after G-097 (achieved 2026-07-21),
ahead of the 8.6 arc (G-099/G-100/G-101). Contract untouched - the
naming decision, piperepl default-on policy, tcltls battery line and
TIP-741 temp-dll characterization were already recorded in the detail
file while proposed.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved goal from the modpod characterization session. The modpod module
carries broken tar-era code (undefined tar::readHeader connect path,
::tarjar::connected reference, con/connected + versionpart typos, malformed
set/lindex constructs, debug stderr, unimplemented wrapped get) while the live
zip surface (make_zip_modpod + self-mount stub) has ZERO automated tests
anywhere - the detail file inventories both with line refs.
Preservation-aware by design: tarjar-system artifacts (vendored tarjar-2.4.3.tm
carrying the G-110 .TclSoCache prior art, the _build #tarjar tree, cli
#tarjar-* build branch, libunknown skip-globs) are assess-only with
per-item user-confirmed dispositions - old tarjar material at
c:/tclmodules/main (incl the intermediate tarpack generation) is preserved and
migrated manually by the user, outside this goal.
Acceptance: defects dispositioned + recorded, tarjar grep clean-or-deliberate,
testsuite (wrap -> require from disk + zipfs paths, binary payload, unwrapped
redirect, both -offsettype forms) passing on tcl9 kit + 8.6 (or recorded G-034
limitation), re-vendored into shellspy.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Two goals split out of the modpod/TIP-741 characterization work, user-approved.
G-109 (libunknown manifest-declared multi-name discovery): a zip-based .tm
declares case-variant and sub-package require names in a manifest at a
well-known internal location, discovered by libunknown at scan time - with
real-disk scan performance preserved (worst-case parity with plain tclsh's
builtin tm handler; libunknown exists to fix slow-drive/large-tree scan cost).
Multi-name .tm are punkshell-only (documented); TIP 590 lowercase single-name
stays the plain-tclsh happy path; extensive-tests bar recorded.
G-110 (extraction cache investigation): whether per-run fresh-temp-dir copies
are necessary or replaceable by a single per-user content-addressed cache
(hash-keyed parent dir). Carries the 2026-07-21 sniff evidence: concurrent
sharing of one copy works; classic Win32 delete refused while mapped; POSIX-
semantics delete succeeds with mappings unharmed (a third option next to TIPs
741/709: unlink-after-load on modern NTFS). Fallback requirement recorded:
punkshell wants a win32/old-Windows fallback (industrial systems on isolated
VMs/old hardware) - capability-probe, classic-safe GC degradation. Precedents
(.NET single-file, critcl cache), sibling-dll sets, AV interplay, and the
cheapest-first implementation surfaces (modpod stub -> suite core patch ->
upstream) recorded.
G-066 note pointed at the new goals.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
All six acceptance clauses satisfied (suite tclsh90s.exe 9.0.5, zig 0.16.0,
machine superbee): thread 143/0 + tclvfs 51/7 GATED with tracked dispositioned
baselines, deterministic across consecutive full runs; tcllib 62328/54 WITH
tcllibc accelerators engaged + tklib 796/18 RECORDED with artifact paths in the
detail file; tk opt-in step with a recorded first census (9865/27, native-
dialog files excluded by default); per-library policy/testargs/notfiles
overridable at invocation; no-totals fails the step in gate AND record mode
(verified); evidence-summary shape documented for the G-103 metadata consumer.
Flips G-107 active -> achieved and archives it (index entry to GOALS-archive.md,
detail file to goals/archive/). Reference sweep: G-103 Notes gain the thread-
payload-refresh forward-pointer (the suite now derives thread naming from the
checkout; the punk905 kit payload still carries the old 3.0.1 copy) and the
evidence-summary-shape pointer; G-108 Notes record that its constrained-test
runs reuse G-107's test_gate generalization + -notfiles knob.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Index entry + detail file for a debug tier of suite_tcl90: build debug-flavoured
runtimes (NDEBUG off / tcl::test compiled in; deeper tier adds TCL_MEM_DEBUG for
the script-level memory command), named with a trailing -dbg<n> suffix, and run
the core suite's normally skipped C-test-command-constrained tests in record
mode (never gated). Kit-family debug members coordinate with G-103; the
TCL_MEM_DEBUG all-or-nothing linking constraint drives the feasibility item.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New goal from the 2026-07-21 discussion: the libraries the buildsuites compile
and ship (thread, tclvfs, tcllib+tcllibc, tklib, tk) get their own testsuites
run under the suite-built shell as named recipe steps with per-library policy -
gate (core test-gate mechanism, dispositioned baselines), record (report
artifacts under out/testreports/), or opt-in (tk). Context carries the source
survey, test_gate.tcl generalization notes, G-102 cost knowns, and the G-103
metadata / 8.6-arc relationships.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Layout fold ("fold stale layout fixes into this"): both layout stores
(src/project_layouts/vendor/punk/project-0.1/bin and the modpod-templates
equivalent) had shipped a stale 2025-era runtime.cmd and a pre-G-096
getzig.cmd - the getzig rename had missed this channel entirely, so
generated projects still received old-named, stale utilities. Both renamed
via git mv AND refreshed to byte-copies of the current bin/punk-runtime.cmd
+ bin/punk-getzig.cmd; the layout src/runtime/Readme.md references updated
in both stores (the layout bin/runtime/ data-dir READMEs are gitignored -
updated on disk only, like the root bin/runtime/README.md); residual
old-name scan of the layout trees clean. The built modpod zips (root
modules/ + bootsupport templates-0.2.0.tm) carry old names until their
normal re-vendor cycles. Layout paths join the goal Scope per the approved
fold.
Flip mechanics: detail file to goals/archive with Status achieved
2026-07-21 (verification in its Progress section: full rename sweep, pins
retargeted and passing 26/25/1/0, drift findings recorded), GOALS.md entry
removed, GOALS-archive record appended (amended Scope + Acceptance
verbatim), reference sweep: G-103 scope parenthetical (both tiers) +
Relationships and the G-099/G-103 sequencing notes annotated with the
achievement; G-096's archive gains a note recording the layout-channel gap
and its closure. goals_lint clean (75 active-index goals, 31 archived).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
First of the confirmed sequence G-097 -> G-103 -> 8.6 arc: the bits/runtime/
tclargs scriptsets and selfsign experiment scripts take the punk- prefix per
the bin/AGENTS.md policy, ahead of G-103 extending the runtime scriptset.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full (evidence in the detail file's Progress
section): concurrency suite green on Windows Tcl 9.0.3 (runtests) and
Tcl 8.6.17 (direct tcltest drive) plus a linux WSL tclsh 8.6.14 run
from a native-filesystem staging - two-writer no-corruption/no-loss
with a clean polling reader, lock timeout naming the holder, dead-pid
and age stale-breaks, non-interactive duplicate-INSTALLER recovery.
Real builds under the re-vendored 0.6.0 run with zero lock timeouts,
zero tripwire warnings and unchanged decisions.
Index entry moved to GOALS-archive.md; reference sweep: G-027's
punkcheck note updated to achieved tense, G-028 gains the
advisory-lock name-the-blocker precedent pointer. Detail file moves to
goals/archive/ in the adjacent commit (pure rename).
punkproject.toml 0.17.3 + CHANGELOG entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance evidence recorded in the archived detail file: PATH-scrubbed
clean-clone demonstration (c:/T/g102, env probed tclsh/fossil/git-free) ran
'zig build bootstrap' end-to-end - zon-pinned sources materialized, runtime +
piperepl variants built, smokes green (static/zip shells, Tk tooltip, tcllib,
tcllibc accelerators via critcl+zig cc), demo shell's tcl::build-info identical
to the fossil-flow build; scrubbed test gate 69552/56075/13468/9 with 8
baselined + fCmd-30.3 proven a SystemDrive scrub artifact (single-file rerun
with the var: GATE PASS), matching the same-day fossil-flow delegated gate
(69552/56040/13503/9 GATE PASS). Environment findings (critcl target probing,
windows Run-step stdio, testsuite base-env needs, firewall consent on first
socket listen) recorded in the detail file for future suite work.
Flip mechanics: detail file to goals/archive with Status achieved 2026-07-21,
GOALS.md entry removed, GOALS-archive record appended (Scope+Acceptance
verbatim), pending-tense G-102 references in G-099/G-103/G-104/G-105 annotated
with the achievement and the settled driver shape. goals_lint clean (77
active-index goals, 29 archived).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Follows straight from G-094's landing: the single save chokepoint
(installtrack save_working_recordset) is in place and the G-094
verification itself logged a transient concurrent-save failure with a
second session active in this checkout - the exact exposure this goal
closes.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full (evidence in the detail file's Progress
section): characterization suites pass with one recorded pin flip,
lifecycle.test pins batch/OO field equivalence (-targets_cksums incl)
and o_record_list coherence across sequential events, the retired-trio
grep is clean, and a full make.tcl build completes with skip/copy
decisions unchanged against pre-refactor .punkcheck state.
Index entry moved to GOALS-archive.md; reference sweep: G-095 notes gain
the chokepoint-achieved pointer, the transient concurrent-save evidence
observed during verification, and the inherited MAX_PATH rider pointer
(G-087/G-094, unaddressed); G-027's punkcheck note updated to achieved
tense. Detail file moves to goals/archive/ in the adjacent commit (pure
rename per the doc-restructure rules).
punkproject.toml 0.17.2 + CHANGELOG entry (punkcheck ships in kits; the
in-shell punkcheck API surface changed with the retirement).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com