The whole pipeline now lives in the zig recipe; Tcl remains the tool exactly
where a tclsh is guaranteed to exist - run by the FRESHLY BUILT suite shell
as build steps:
- New steps (native-host builds): smoke (static shell patchlevel; zip shell
patchlevel + attached tzdata/autoload), tklib / tcllib (their own installers,
batch, -pkg-path as a cached output dir installed into the prefix, + package
smokes incl withdrawn-Tk tooltip), tcllibc (critcl driving zig cc via the
tracked critcl_zig.config, module list parsed from tcllib's version.tcl,
pinned-zig dir prepended to PATH, + accel smoke), test-gate (tools/
test_gate.tcl - the parsed-totals gate vs expected_test_failures.txt,
-Dtestargs passthrough).
- Package landing moves into the recipe proper: thread pkgIndex.tcl
(build_tclthread), tk pkgIndex.tcl (build_tk), and the tclvfs script package
incl .in-template substitution + dll (build_tclvfs_shared
install_tclvfs_package) - all hooked to the install step.
- Step scripts: tools/test_gate.tcl, tools/suite_smoke.tcl, tools/pkg_smoke.tcl
(run under the built shell; assertions live in Tcl).
- Two windows-childproofing findings encoded: built-shell Runs execute the
CACHED artifact (no ../lib/tcl9.0 beside it) so each such Run gets
TCL_LIBRARY pointed at the source tree's script library (the zip smoke
deliberately excluded - its attached library is the thing under test); and
cached (non-side-effect) Runs spawn with stdout IGNORED, leaving the tcl
child without a stdout channel ('can not find channel named "stdout"',
critcl's logging) - such runs capture stdout to give the child a real pipe
while keeping caching.
- suite.tcl: thinned to the fossil dev flow - fetch live checkouts (git kind
now handled in the main loop for critcl's pin), stage the recipe, delegate
to the staged steps (run_zig_steps; 'test' delegates to test-gate). Default
-steps and the bootstrap default grow to the full pipeline short of
test-gate. critcl_zig.config + expected_test_failures.txt join both staging
lists. Docs updated (README two-flow section, sources.config two-surface
header, overlay section); .gitignore learns .zig-cache/ and zig-pkg/ (zig
0.16 extracts fetched packages into zig-pkg/ beside the manifest).
Verified (fossil flow): full pipeline PASS - suite_smoke static+zip, tklib
tooltip:2.0.4 under withdrawn Tk, tcllib md5/sha1/cmdline, tcllibc:2.0 with
md5-critcl-accel:1; 'suite.tcl test -testargs {-file http.test}' delegates to
the gate step (528/519/9/0 GATE PASS).
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
Batched punkcheck-managed build outputs from 'make.tcl modules' +
'make.tcl bootsupport' after the G-094 landing: punkcheck 0.4.0 -> 0.5.0
and punk::mix::cli 0.5.0 -> 0.5.1 snapshots (per the G-094 prompt
re-vendor note - make.tcl now runs the unified lifecycle), plus
opportunistic catch-up of stale snapshots (libunknown 0.2.0 -> 0.2.1,
punk::config / punk::lib / punk::repl content syncs from current built
modules).
Verification under the new punkcheck: 'make.tcl modules' x2 and a full
'make.tcl project' complete exit 0 with skip/copy decisions unchanged
against pre-refactor .punkcheck state - copied: 0 on every batch phase,
kit installs skip 'no change detected' (the sole punk905 rebuild traces
to the newly promoted tclsh905 runtime, a genuinely changed source).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
suite_tcl90 gains the no-tclsh source path:
- build.zig.zon: content-hashed manifest pinning each source as a fossil
per-checkin tarball (tcl 1a9c3b9d96 / thread caa1d3aa30 / tclvfs f082c47f9b
/ tk effef6c657 / tklib 2d53beafc0 / tcllib c784f6fda4 - the exact checkouts
the promoted punk905 runtime was built from) plus critcl 3.3.1 as a github
archive. All lazy: the fossil dev flow never triggers a fetch. Refresh =
bump a pin (zig fetch --save). Verified honored under --build-file
build905.zig.
- build905.zig mode split: from the staged recipe copy the full graph
registers as before; from the TRACKED suite dir (sources.config present,
no ../tcl905) only the staging steps register. 'zig build stage'
materializes pinned sources + a recipe copy into ../_build/<suite> (the
same layout suite.tcl's fossil staging produces - both flows share the
staged invocation, and the stage dir derives from the suite folder name so
copy-and-tweak isolation holds). 'zig build bootstrap' chains the staged
build: nested zig invocation with suite.tcl-parity cwd (parts of the
recipe resolve sources cwd-relative), forward-slash prefix (the prefix
flows into -DTCL_PACKAGE_PATH as a C string literal - backslashes broke
the stubs compile), per-zig-version shared cache dir, hermetic-child env
scrub, ReleaseFast default.
- tools/stagetree.zig: host-compiled materializer. Pinned mode keys a
.stage-materialized marker on the dependency's content-addressed cache
path (pin bump = invalidation, stale trees deleted so orphans cannot
survive); always-mode for recipe items; fossil/git checkouts at the
destination are never touched (tested).
Verified: 'zig build stage' against the fossil-populated stage refreshes
only the recipe copy (checkouts untouched, fossil changes empty); a full
copy-and-tweak suite copy (suite_tcl90zt) ran 'zig build bootstrap' from
nothing but the tracked tree + pinned zig - all 7 sources fetched/staged
from the manifest, all four shells built; tcl::build-info reports the same
9.0.5+1a9c3b9d... as the fossil-flow build and the zip shell boots its
attached library (tzdata + autoload).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
installtrack/installevent is now the only implementation of the .punkcheck
record lifecycle (targetset init/add-source/started/end). Each event takes
a persistence policy at start_event (-persistence eager|deferred): eager
keeps the current per-op read-modify-write behaviour; deferred accumulates
updates in the installtrack's in-memory working recordset until an explicit
$installer flush (event-scoped save). QUERY stays never-persisted.
punkcheck::install rebuilt as a tree-walking OO consumer in deferred mode -
its records now carry the full field set (-metadata_us/-ts_start_transfer/
-transfer_us/-cksum_us and -targets_cksums incl all-targets mode), pinned
field-equivalent with OO-installed records by the new lifecycle.test.
Legacy zero-caller proc pipeline (start_installer_event, installfile_begin/
started_install/finished_install/skipped_install) retired to error-with-
pointer shims; installfile_help rewritten for the OO lifecycle; the live
shared engine installfile_add_source_and_fetch_metadata is unchanged.
punk::mix::cli's commented-out legacy call sites removed (0.5.1, no
behaviour change).
Single save chokepoint: every lifecycle write funnels through installtrack
save_working_recordset - the G-095 attachment point.
Coherence and latent fixes (each pinned in lifecycle.test):
- start_event refreshes the working recordset; sequential events on one
instance no longer clobber prior targetset writes (end/end_event now
clears the active-event slot, so a second start_event is valid)
- event reconstruction maps record -ts_begin/-ts_end to constructor opts
(flush no longer rewrites prior event history timestamps)
- installtrack as_record: stray backslash-space wrote -name with a
trailing space, breaking by-name lookup after any flush
- get_recordlist misspelled variable; targetset_dict nonexistent helper
- extract_or_create_fileset_record stdout print removed (isnew returned;
targetset_init reports via debugchannel); dead targetset class removed
Pin flip (recorded in installtrack.test): the full-lifecycle test's
end + end_event double-end now correctly errors - lifecycle uses one of
$event end / $installer end_event, matching all real consumers.
Suites: punkcheck install/installtrack/lifecycle 78/78, punk/mix subtree
incl cli prune.test 144 pass / 1 constraint-skip on native Tcl 9.0.3.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Generation of the configure-products a fresh checkout lacks moves from
suite.tcl tree-writes into the zig recipe as build-cache overlays:
- tclUuid.h / tkUuid.h / threadUuid.h: wrapfiletofile Run outputs consumed
via overlay include dirs added FIRST per module (stale tree copies from
pre-G-102 flows can never shadow; the LazyPath also carries the step dep).
The unused addUpdateSourceFiles tree-write variants (build905 prepare-source,
build_tclthread) are removed.
- tclsh.exe.manifest: configure-time substitution (tcl.h parsed by the new
build_common.zig helpers); tclsh.rc compiled from an overlay COPY beside the
generated manifest because rc resource references resolve rc-file-relative
before include paths. Both tclsh exes switch to .include_paths LazyPaths.
- wish.exe.manifest: overlay dir first in tk.rc include_paths (RT_MANIFEST
resolves through rc include paths - the arrangement the tk build already
relied on). tk.rc itself stays tree-compiled (lives in win/rc, no stale risk).
- thread.rc: compiled from an overlay copy with the tcl.h include inserted
(the historical checkout edit is normalized if a mutated tree is staged);
the staged tclthread checkout's thread.rc edit has been fossil-reverted.
- build905.zig: redundant configure-time top-level library install loop
removed (install_library_tree already covers it); dead zlib stage copy and
the suite.tcl generation blocks removed (read-only version parsing kept for
smokes/logging).
Verified: full staged-mode rebuild PASS (all smokes incl tklib/tcllib/tcllibc);
built binaries carry the overlay products (tcl::build-info reports
9.0.5+1a9c3b9d..., tclsh manifest version 9.0.2.905, tk dll manifest + tk
checkout uuid, thread dll uuid; thread dll's empty FileVersion matches the
pre-change binary - upstream quirk). Source checkouts stay pristine (fossil
changes empty). Core test gate: 69783 run, 12 failed - 11 baselined plus
http-4.14.2, a network-timing flake that passes on isolated rerun (528/519/9/0).
tclsh90sprzip.exe install into out/bin is currently blocked by an open user
application holding the file; the product builds identically into the zig
cache and installs on next run once released.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Readonly reference checkout of the community Tcl 9 port of classic
Expect (alpha, Linux-tested, unix-pty only - no ConPTY/windows
backend). Full assessment in the G-061 notes: reference for expect
primitive semantics, candidate unix-backend tool at arm's length,
pty-allocation reference. G-020/G-044 get pointers, plus stale
"candidate goal drafted" phrasing updated to name G-061.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
G-102 continues in a parallel session; this session takes the punkcheck
arc. G-094 is the unification prerequisite for G-095 (concurrent-writer
safety): one lifecycle implementation with an explicit eager/deferred
persistence policy and a single save chokepoint.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Sequencing per the recorded plan: suite_tcl90 arc closed (G-096/G-098
achieved, punk905 promoted 2026-07-21), so the driver-shape work starts
now, ahead of the 8.6 arc (G-099 born onto the chosen shape).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User direction 2026-07-21 recorded in G-103: piperepl-patched runtime
executables must carry 'punk' in the name (e.g tclsh905punk.exe) so
patched and unpatched are never confusable - now an Acceptance item, with
the open design questions captured (how to encode tcl patchlevel + punk
version, separator choice; existing sub-namespaces punkNNN kits /
tclsh-runtimes / punk- utilities; metadata carries authoritative versions
so filenames stay human-distinguishing). The suite's tclsh90spr/sprzip
are flagged as internal working names in patches/README.md pending the
scheme.
Also noted: punkbin pushes of suite runtimes are deferred until family
members carry Thread etc in the attached zip and the punk-named pr
variants exist - publication follows G-103's artifacts, not the interim
tclsh905/punk905 shapes. goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Per the *_beta convention (trial before punk tests, drop the suffix on
acceptance): punk9wintk905_beta.vfs renamed to punk9wintk905.vfs, the
runtime redeployed as bin/runtime/win32-x86_64/tclsh905.exe (fresh copy
of the suite's tclsh90szip.exe, self-containment smoked), and the
mapvfs.config entry becomes 'tclsh905.exe {punk9wintk905.vfs punk905
zip}' with the promotion recorded in the comment block. tcludp joins the
promoted vfs via vendorlib_vfs.toml (daily-driver expectation - teelog
workflows), installed by make.tcl vfslibs.
Built punk905.exe verified: kitcheck full pass (Thread/vfs/vfs::zip/
sqlite3/twapi/tcllibc/md5-accelerated/tk 9.0.2) plus udp 1.0.13; 'shell'
round-trips (repl 0.5.2, libunknown 0.2.1); kit-hosted console suites
71/71 via the src-mode child launch. Beta artifacts (bin/punk905_beta.exe,
runtime tclsh905_beta.exe) removed. A piperepl-runtime punk kit
(tclsh90sprzip base) remains G-103 kit-family territory.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
All acceptance items met and recorded in the goal file: clean-checkout +
punk-getzig-pinned-zig build PASS (shallow-path/longpaths MAX_PATH caveat
recorded; c:/T available as a shallow test base per user), recovered +
rebased piperepl patch set with the G-103 opt-out gate policy and full
behaviour matrix (automated rows + user interactive verification),
tclsh90spr/tclsh90sprzip products, per-version punk-getzig into versioned
dirs (all four paths verified), both-VCS tracking + samplesuite1/
vendorbuild reconciliation, bin/AGENTS.md naming policy + punk-getzig
rename. Flipped to achieved 2026-07-20 and archived; GOALS/GOALS-archive
updated; achieved markers added to the six referencing goals flagged by
the lint reference sweep (G-097, G-100, G-102, G-103, G-104, G-106).
goals_lint clean (79 active, 27 archived).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Fresh clone (shallow path + core.longpaths - the deep-path first attempt
hit windows MAX_PATH on the modpod template trees, caveat recorded) ->
the clone's own punk-getzig fetched 0.16.0 (mirror chain, minisign,
versioned dir) -> cold-cache suite build PASS: 9.0.5 static/zip/pr/przip
shells with recipe-generated configure-products, zip shell smoked, all
tk/tklib/tcllib/tcllibc legs green.
Cold-log 'failed command:' blocks diagnosed as BENIGN zig 0.16 behaviour
(build_runner prints that block for any step with nonempty result_stderr
even on success) triggered by our own tools' informational stderr prints
- zipfs_mkzip/mkimg call echoes now go to stdout and wrapfiletofile's
octet count is removed; rebuild shows zero occurrences, PASS.
All G-096 acceptance items are now met - achieved flip pending user
confirmation.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The zig version is now the first argument (default = the suite pin,
0.16.0) and each version installs into tools/zig-x86_64-windows-<version>
- the zip's own root folder name, so the old rename-to-tools/zig step and
its post-ExtractToDirectory lock retry/GC dance are gone. Installed-check
warns if the exe's reported version mismatches its versioned folder.
Documented limitations: dev builds (/builds/) and pre-0.14.1 releases
(old zig-<os>-<arch> naming) are not handled - the punkbin flat tools/
mirror path covers those if one must be pinned. The bash side stays an
honest stub with the same argument convention.
Rewrapped via scriptwrap::multishell (punk905_beta src script) ->
bin/punk-getzig.cmd (the untracked .ps1 twin byte-synced locally).
Verified all four paths through the polyglot: explicit present version,
no-arg default, existing-zip verify+extract (0.15.2 zip with no dir), and
the FULL network path (0.15.2 artifacts removed then re-materialized:
mirror latency selection -> download zip+minisig -> signature verified ->
versioned extract -> ZIG VERSION 0.15.2). G-096's remaining item is now
the final clean-checkout re-verification only.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User verified tclsh90spr 2026-07-20: interactive sessions normal with and
without TCLSH_PIPEREPL=0 (closes the G-096 matrix's residual user-level
check), and basic punk features work on the bare pr shell via repo tm
paths (raw mode twapi-reliant). Via './tclsh90spr src/make.tcl shell' the
powershell console-mode fallback engaged and raw mode worked - modulo
consolemode_server_async.ps1 noise and an early server shutdown.
New G-106 captures the requested direction: maintain the fallback as a
dependable raw-mode path for twapi-less runtimes (suite shells/kits),
hardening the known weak points recorded at creation - argv0-derived
pstooldir resolution (works for make.tcl shell by construction, little
else; kits need G-089 scriptlib delivery), server early-shutdown +
startup noise, and the unmarked experiment variants beside the canonical
script in scriptlib/utils/pwsh. Priority rises if G-103's zig-built twapi
investigation proves impractical - cross-noted there.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The recovered 2024 TCLSH_PIPEREPL patch applies cleanly to current
core-9-0-branch tclMain.c (8 hunks, offset 4). Tracked as
patches/tclMain_piperepl_905.c = stock 9.0.5 + patch + gate-default flip:
ENABLED unless TCLSH_PIPEREPL=0 (2024 was opt-in set-and-not-"0") per the
G-103 punk-kit policy - the goal's Goal/Acceptance were aligned to that
policy first at user request. Era files kept unmodified as recovered
artifacts; patches/README updated (status, gate semantics, known
tcl_interactive early-link divergence when the gate is open).
build905.zig gains tclsh90spr (per-source construction mirroring tclsh90s
with both tclMain compiles - unicode + TCL_ASCII_MAIN ansi - swapped to
the patched file; stock products stay byte-for-byte unpatched) and
tclsh90sprzip (zipfs_mkimg wrap of the pr exe, -infile form). patches/
added to suite.tcl's staged recipe items. Full suite build PASS.
Behaviour matrix recorded in the goal: 9/9 stock-equivalence rows
IDENTICAL (script-arg / script-consuming-stdin / piped-commands x
unset/0/1 - open-gate plain scripts behave stock; unread piped payload
never eval'd); feature row proves buffering verbatim into
::tclsh(inputbuffer) (write-trace capture), console reopen success and
repl landing; =0 feature row identical to stock; przip variant identical
to pr - the G-103 punk-kit precursor works.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User decision 2026-07-20: other build systems/distributions already
provide completely-plain tclsh executables - not a punkshell product role.
G-103's 'plain' family member (no piperepl patch, batteries attached) is
plain enough for our purposes; the truly bare bootstrap-intermediate
tclsh (tclsh90szip-class, which already satisfies G-018's substance:
stock invocations, no punk namespaces, self-contained) remains readily
accessible as an ordinary suite build product under _build/<suite>/out
but is deliberately not showcased or published.
G-018 closing note records all of this; G-103 gains the plain-niche
boundary paragraph (scope's subsumption-review item resolved and
removed, GOALS.md mirror updated); G-102's relationship line updated.
goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
All tcl9 zip kits failed the 'shell' subcommand with "could not find
interpreter code": the repl codethread could not resolve root-level tm
packages (commandstack, via punk::packagepreference) after any subdir tm
(punk::args) had resolved on the same path. zipfs_tm_UnknownHandler's
static-path can_skip_update state was WRITTEN keyed by the tm-list root
(currentsearchpath) but READ keyed by the namespace-subdir searchpath
actually scanned (specificsearchpath) - so a punk/ scan poisoned the
ROOT's skip map and later root-level requires were skipped as
known-absent. Only zipfs tm paths take the skip branch, which is why
src/dev filesystem launches never showed it; kits have exactly one
(zipfs) tm path so every shell boot hit it. Independent of the epoch-copy
unsoundness fixed earlier today (reproduced with a fresh libunknown init).
Fix: both added-map writes now key by specificsearchpath, matching the
reader and libunknown::init's indexbase keying. Version bumped to 0.2.1
with history note (the file rename itself rode the previous commit via a
staged git mv; this commit carries the 0.2.1 content).
_vfscommon refreshed via make.tcl modules + vfscommonupdate + vfs (also
picks up today's punk::lib epoch-export, punk::repl collect-guard and
punk::config PUNK_FOSSIL_STORE changes); 5 kits rebuilt. Verified:
ordered probe (subdir-then-root require in a fresh thread) fails on
kit-bundled 0.2.0, passes with 0.2.1; 'shell' now reaches the repl and
evaluates on punk905_beta, punk902z and punk91; full native runtests
sweep twice at machine baseline (1037/1021/15/1 exec-14.3 only).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User requirements batch 2026-07-20 integrated:
- G-103 runtime kit family: buildsuites produce self-contained kits whose
info library and batteries live in the initially attached zip - PLAIN
tclsh kit (Thread + tclvfs/vfs::* + tcllib/tcllibc), PUNK kit (piperepl
applied, ENABLED BY DEFAULT with env opt-out - gating review agreed; the
plain kit serves stock semantics), BI kits adding libraries we build (Tk
now; sqlite3/tdom easy/moderate futures; twapi flagged needs-investigation
under the zig-only policy). tcllib+tcllibc in all members (user lean,
agreed). Artifact metadata in punkbin (+compatible repos) surfaced by the
runtime scriptset list/use. G-018 flagged as substantially subsumed. 8.6
variant deferred through G-101 (static-vfs/metakit questions noted there).
- G-104 make.tcl buildsuite surface: list / info <suite> / build <suite>
with suites SELF-describing (info contract survives the G-102 driver
migration; copied trees appear automatically). mapvfs single-kit/list
wishes noted as sibling ergonomics.
- G-105 cross-target builds: -target as an invocation dimension (suite
folders stay version-named), linux x86_64 first verified via local WSL
with its own test baseline; zig tier findings VERIFIED and recorded -
the freebsd asymmetry suspicion is inverted (freebsd AS TARGET was the
gap, closed in zig 0.16 for FreeBSD 14+ with CI-tested x86_64/aarch64;
building FROM freebsd was already fine); macOS-as-target (SDK/frameworks)
recorded as the hard case; fully-static-musl dlopen limitation drives a
dynamic first linux target.
Cross-edits: G-096 piperepl matrix gains the kit-default policy update
(punk kits opt-out not opt-in); G-101 records the 8.6 kit-family
dependency; G-102 notes the family/target/surface as build-graph products.
goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Direction agreed 2026-07-20: the whole buildsuite pipeline becomes
drivable with only the pinned zig toolchain present. Pre-tclsh phases
(fetch, configure-product generation, compile) move into the zig build
layer with sources in a content-hashed zon-shaped manifest (fossil
sources pin as per-checkin tarballs - '-refresh' becomes 'bump the pin';
fossil-checkout flow retained as the dev alternative); post-tclsh phases
(tcllib/tklib installers, critcl, parsed-totals test gate) stay Tcl
scripts run by the FRESHLY BUILT suite tclsh as build steps. Acceptance
includes a PATH-scrubbed no-tclsh end-to-end demonstration, preservation
of the copy-and-tweak retargeting property, and the recorded rejection of
a bash+powershell polyglot for this layer (polyglot craft remains the
acquisition layer's mechanism - punk-getzig/getpunk first contact).
Cross-references: G-096 direction note marked RESOLVED -> G-102 (its
remaining items close on the current suite.tcl shape regardless); G-099
sequencing now weighs birthing suite_tcl86 onto the chosen driver shape.
goals_lint clean (76 active, 26 archived).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
A developer (no llm assistance, no punkshell modules - the driver stays
dependency-free plain tclsh) can now copy the suite tree and retarget
sources declaratively: urls/refs/pins live in sources.config (plain line
records 'source <name> <kind> <url> <ref> <dir>', parsed never executed;
fossil sources + the critcl git pin), and the build stage derives from the
suite FOLDER name so a copied tree stages into its own _build/<name>
isolated from the original. -tclbranch becomes a per-run override of the
declared tcl ref. Depth limit documented where the tweaker will read it:
same-major url/ref changes are config-only; version-class changes ripple
into build905.zig (checkout dir names, version-derived tm/dll/manifest
names).
README gains a Retargeting/copying section; its Sources section corrected
(stale per-stage fossil-store location from before the ~/.punkshell/fossils
move, and the G-098 sources were missing from the table).
Direction recorded in G-096 notes (2026-07-20): toml requirement DROPPED
for binary-build buildsuites; long-term intent is bootstrapping without a
pre-existing tclsh (zig acquisition = accepted root dependency; the
freshly built tclsh is the legitimate intermediate for tcllib/tklib
installers and critcl); zig-driver-vs-polyglot question recorded with the
current recommendation (zig hybrid; polyglot counselled against).
Verified: suite.tcl test -testargs '-file assocd.test' passes through
config load + fetch skip-logic + gate on the existing stage; stage
derivation for a copied name resolves to _build/<copyname>.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
G-098 (suite_tcl90 Tk+tklib, tcllib/tcllibc via critcl, test gating)
flipped to achieved 2026-07-20 and archived - all acceptance items
recorded in the goal file across increments 1-7 (Tk 9.0.2 + tklib,
tcllib+tcllibc ~248x hashing speedup, parsed-totals test gate with
dispositioned baseline, full punkshell runtests parity with the Tcl903
baseline including Tk suites unskipped, kit-hosted runs fixed).
New proposed goals mirror the arc for fossil core-8-6-branch (8.6 stays
punkshell's real Tcl 8 target; current punk86-class kits ride prebuilt
third-party tclkits - a provenance gap):
- G-099: suite_tcl86 core - zig-only 8.6 runtime + thread 2.8-branch +
tclvfs + parsed-totals core-test gate with its own dispositioned
baseline. Records expected differences (no zipfs, entry-point/bundled
lib divergences, no tcl::process).
- G-100: Tk 8.6 + tklib + tcllib/tcllibc via critcl on the 8.6 runtime +
punkshell runtests census against a native 8.6 kit baseline.
- G-101: kit container strategy without zipfs (metakit/tclkit lineage vs
cookfs vs zipvfs boot; TEMP_REFERENCE/metakit + KitCreator guidance) -
separated so the well-understood ports stay incrementally landable.
Sequencing recorded in each goal: recommendation is to close G-096's
remainder and run the punk905_beta trial to promotion before activating
the 8.6 arc, so shared suite scaffolding settles before it is forked.
goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Under punk91/punk902z/punk905_beta, '-include-paths modules/punk/console/***
-jobs 16' failed all 7 files with zero tests run: child processes boot via
plain kit script dispatch, preloading kit-stamped punk packages
(punk::console 0.7.2) before the payload's src paths apply - the suites'
pinned 'require punk::console 999999.0a1.0-' then version-conflicts and
the child exits 1 (the known shadowing runtests already warned about).
Fix: when the host is a PUNK kit (kit container heuristics AND the
::punkboot namespace marker from punk_main.tcl boot) children launch as
'kitexe src child_test_runner.tcl ...' so they boot the project's src dev
modules - matching what the payload selects. Non-punk kit containers (e.g
tclsh90szip.exe: zipfs app mount, no punk boot) keep the old warning and
get no extra arg. runtests_run_child_process gains a required exemodeargs
param (tpool info args/body replication unaffected).
Tally: file-level failures are not test results, so a FAIL run could sit
beside 'Failed 0' unexplained (user report). The tally line now appends a
fail-coloured 'Testfiles-failed N' whenever testfiles failed.
Verification: console suites 71/71 under punk905_beta, punk91, punk902z
(previously 0 run / 7 files failed); native Tcl903 + suite tclsh90s
unchanged 71/71 with no modeargs; tclsh90szip warning path passes; tally
demo shows 'Total 0 ... Failed 0 Testfiles-failed 1'.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Copying ::punk::libunknown::epoch verbatim into a fresh interp/thread
carries per-epoch 'added' maps that drive zipfs_tclPkgUnknown's
can_skip_sourcing short-circuit - sound only in the interp that performed
the scans. Packages the donor obtained at an earlier epoch (or with no
unknown call: Thread is baked into thread::create'd threads) are absent
from the donor's current-epoch map, so recipients skip their pkgIndex
sourcing and requires fail where stock tclPkgUnknown would succeed.
Bit deterministically as repl_console_backend_tkconsole under the suite
9.0.5 runtime: 'package require Tk' bumps the epoch pre-init, the
codethread inherits the post-bump sparse map, the code interp then can't
find vfs/Thread/registry, its init aborts before the G-001 conredirect
junction vars exist, and the first pending-collect error left the repl
reader inactive until the driver failsafe. Tcl903 escaped only by an
accidental extra epoch bump in its code interp (fresh map, full rescan).
Fix: punk::lib::libunknown_epoch_export (PUNKARGS-documented) - epoch
record with every 'added' map emptied; counters/untracked/scripts/index
globs preserved. Used at all four propagation sites (interp_sync,
snapshot, repl %lib_epoch%, repl safe-arm). Hardening: the repl
pending-collect now tolerates missing junction vars so a code-interp init
failure can't wedge the reader.
Also: test socketpairs pinned to -myaddr 127.0.0.1 (all-interfaces
listens raised windows firewall consent popups for each newly built test
exe - user datapoint).
Verification: consolebackends 3/3 both runtimes (suite 42s->14s); full
runtests sweeps identical on suite runtime and Tcl903: 1037/1021/15/1
with the sole failure exec-14.3 (documented machine baseline). G-098
acceptance sweep met. Pre-existing PUNK_TEST_TK opt-in quirk noted in the
goal (silent early end, both runtimes, out of scope).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New src/vfs/punk9wintk905_beta.vfs modelled on punk9wintk903.vfs: suite-built
tk9.0/tklib0.9/tcllib2.0/tcllibc/thread3.0.1/vfs1.4.2 payload (tk + thread
dlls in bin/ per the ../../bin pkgIndex convention; tclvfs dll rides inside
vfs1.4.2 - vfs.tcl loads from $::vfs::self), plus twapi5.0.2 + sqlite3.51.0
carried over from the 903 vfs for basic human trial. tcludp deliberately
omitted (one vendorlib_vfs.toml target line away if -teelog trials wanted).
Runtime = _build/suite_tcl90/out/bin/tclsh90szip.exe copied (untracked) to
bin/runtime/win32-x86_64/tclsh905_beta.exe - static tclsh 9.0.5 with the
tcl library in its attached zip; the zip wrap merge_overs that into the kit
so tcl_library survives (same mechanism as tclsh902z->punk902z).
Built with 'make.tcl vfs -confirm 0': punk905_beta.exe INSTALLED; kit smoke
passes - Thread/vfs/vfs::zip/sqlite3/twapi/tcllibc(md5 C-accelerated)/tk
9.0.2 all load with functional pokes, punk boot machinery active.
Beta-kit policy recorded in mapvfs.config + goal: wrap fresh suite runtimes
as *_beta kits even before punk tests pass, for early interactive trial.
Future noted: 'make.tcl vfs <kitname>' single-kit build + configured-kit
listing; move tclvfs/thread into the runtime-attached zip.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
suite.tcl 'test' is now a gate: full tcltest output logged, totals parsed
(all.tcl's exit code does not reflect failures), failed test names compared
against expected_test_failures.txt - unexplained failures fail the action;
stale baseline entries are noted on full runs. Totals on core-9-0-branch
9.0.5 / zig 0.16.0: 67281 run / 55835 passed / 11435 skipped / 11 failed,
GATE PASS, deterministic across two full runs. The 11 are dispositioned in
the baseline: 6 fCmd (OS username vs profile-dir machine trait), 2 filename
(admin-share self-globbing), 2 safe-stock (install-layout accessPath
tokens), 1 console-bug-f10d91c2 (powershell driver yields empty result in
batch context; semantics verified independently by G-076 kill procedure).
Runtime package plumbing gaps closed (built artifacts without install
wiring): thread pkgIndex generated (lib/thread3.0.1 -> bin dll), registry
dll install artifact hooked to install-libraries (was orphaned - registry
1.3.7 + dde 1.4.6 now load), tclvfs script package installed with vfs.tcl
+ pkgIndex.tcl generated from .in templates (vfs 1.4.2 + vfs::zip 1.0.4).
punkshell runtests under the suite runtime: checkbugs 5/5, opunk
backends.test PASS (Tk-widget console suite runs unskipped on the
suite-built Tk), repl consolebackends 2/3 - repl_console_backend_tkconsole
open (code-interp console_pending_out junction init missing; DRIVER-DONE
timeout-failsafe).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
tcllib pure side via its own installer (explicit -pkg-path; driver now unsets
TCLLIBPATH/TCL_LIBRARY/TK_LIBRARY for hermetic child shells after the default
libdir followed inherited TCLLIBPATH to C:/TCLPKGS - additive pollution
verified and removed). install-libraries now installs the whole tcl library
tree (its own pkgIndex references msgcat/opt/... subdirs the piecemeal
install missed). critcl pinned 3.3.1 (git) + tracked critcl_zig.config
(zig cc -target x86_64-windows-gnu); driver replicates sak's direct critcl
invocation over the 21 declared files -> tcllibc.dll at out/lib/tcllibc
(provide 2.0). Evidence: md5 accel(critcl)=1; sha1 5MB critcl 12.3ms vs
pure 3.06s (~248x) - the punkcheck hashing pain quantified and fixed.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Installer behaviour checked first per user caveat: module exclusions,
app-script generation, doc options, and the aggregating top-level
pkgIndex.tcl (gen_main_index) - not a straight copy; critcl DSL stubbed to
no-ops (pure-tcl). Driver runs it with the suite-built tclsh in batch mode,
packages only, landing out/lib/tklib0.9. Smoke: package require Tk +
tooltip -> 2.0.4 in the suite shell.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Per user direction and draft refinements 2026-07-20: matching tklib alongside
Tk (pure-tcl, own installer.tcl where it does more than straight copy);
tcllib installed via its installer machinery (installer.tcl/sak.tcl checked
for non-copy behaviour) with critcl-built tcllibc driving zig cc; the
totals-parsing test gate owns the 72-failure triage. goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The build016 experiment port lands in the tracked recipe (root_module/
createModule creation, addLibrary+linkage, .root_module.* method sweep,
linkSystemLibrary options arg, array_list.Managed, Io.Dir dir-walks with
b.graph.io, wrapfiletofile ported to the 0.16 entry/Io idiom). 0.14 support
deprecated per user direction; 0.14.1 remains archived on punkbin. Verified
on the pinned default (bin/tools/zig-x86_64-windows-0.16.0): build PASS,
shells 9.0.5, tcl-test parity 557/357/200/0 identical to the 0.14.1 build.
punk-getzig payload pins -> 0.16.0 (windows zip + linux tarball), re-wrapped
checkfile ERROR-free, ps1 twin refreshed. punkbin commit 54714d7 holds the
0.16.0 archive; push pending gitea recovery (server currently 500s).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
vqtcl was an old-tclkit experiment with no confirmed public upstream - wiring,
helper module, staging and docs removed (future tclkit work: TEMP_REFERENCE/
metakit + KitCreator). New 'test' action runs tests/all.tcl on the suite-built
static shell with -testargs passthrough; verified assocd/util/lindex: 557 run,
357 passed, 200 constraint-skipped (no C test commands in a release shell),
0 failed. install-libraries tm filenames synced to the tree's provided
versions (tcltest-2.5.11, http-2.10.2, platform-1.1.1) - the 2024-era names
made 'package require tcltest' fail on a filename/provide version conflict.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Recipe: b.host -> b.graph.host; redundant second UNICODE tclMain add into the
objs lib removed; exe's ansi tclMain compiled with -UUNICODE -U_UNICODE
-DTCL_ASCII_MAIN (zig cc windows-default defines made it a duplicate UNICODE
compile under 0.14.1 - lld duplicate Tcl_MainExW/commons). Driver: per-item
recipe staging, per-zig-version local caches (.zig-cache-<ver>; caches must
not be shared across zig versions), zig resolution -zig > PUNK_ZIG > pinned
bin/tools/zig-x86_64-windows-0.14.1 > PATH. Verified: PASS on 0.14.1 AND
regression PASS on 0.14.0-dev.2074; pinned-default no-option run PASS.
Pinned archive minisign-verified and published to punkbin (abcd87c).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Scriptset (src/scriptapps/bin) and the generated bin wrapper renamed; the
untracked bin/getzig.ps1 twin replaced by punk-getzig.ps1 (byte-copy of the
.cmd - launchability convenience for cmd.exe-or-powershell starts). Payload
improvements: self-references updated, and the ziglang.org release URL now
derives its version from the single $releasearchive pin (was a separately
hardcoded 0.15.1 vs 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/AGENTS.md gains the punk- naming policy section
(exceptions: dtplite/sdx/kettle wrappers, getpunk; sweep of bits/runtime/
tclargs/selfsign is G-097).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
First real buildsuite: build905.zig (verbatim G-076-validated recipe) +
helper modules + tools, driven by suite.tcl which stages the recipe into
src/buildsuites/_build/suite_tcl90, arranges sources (tcl fossil
core-9-0-branch --nested with FOSSIL_HOME isolation; thread/tclvfs trunk;
zlib from the tcl tree's compat/zlib; vqtcl from a local dir), generates the
configure-products fresh checkouts lack (tclUuid.h, tclsh.exe.manifest,
thread.rc include), builds and smoke-tests. Verified PASS: static + zip
shells report 9.0.5 (checkout 1a9c3b9d96), Thread 3.0.1 builds from current
trunk (new generated-include fix in build_tclthread) and loads. The 2024
TCLSH_PIPEREPL/tclZipfs/tclCmdIL patches are now tracked under
suite_tcl90/patches with a semantics README (not applied by default builds).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Blanket /src/buildsuites ignores removed from .gitignore and
.fossil-settings/ignore-glob; retired /vendorbuilds/ ignores removed with
them. src/buildsuites/_build remains ignored via the existing _build globs.
samplesuite1 sketch marked as such, buildprefix moved to the _build
convention (vendorbuild concept retired per user decision 2026-07-20).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Sweep: G-096 detail and the punk::lib gate comment now point at the archived
path with achieved phrasing. goals_lint clean (72 active, 25 archived).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::repl (pending 0.5.2): repl_handler's full 'chan configure' probe is now
guarded - on runtimes carrying the upstream f10d91c2d3 fix a dead console is
DELIVERED as a readable event and the probe errors ('couldn't read console
mode: broken pipe'); previously this backgrounded and left the repl idle with
its reader inactive. Terminal input loss now routes through new
repl::console_input_lost - the same teardown console_watchdog uses (helper
shared by both paths; watchdog probe and message unchanged).
punk::lib (pending 0.5.0): check::tclbug_console_deadspin_fixed_in = 9.0.5
after the G-039 kill procedure passed on a zig-built core-9-0-branch runtime
with the watchdog disarmed (clean script-visible eof exit 0.2s after conhost
kill). One edit flips both consumers: 'help tcl' warning and watchdog arming.
Regression-verified on affected 9.0.3: bug=1, watchdog armed, rescue at 1.9s
via the shared teardown. Suites: console+repl+lib families 115/115.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The stale copy (2026-07-19 20:55 build) survived three make.tcl bootsupport
runs: two in-session runs failed the copy with 'invalid argument' (destination
held open - a running shell's zipfs mount on the bootsupport modpod, the
G-087-era self-lock class) and the user's post-shell-close rerun left it
untouched (cause unobserved - if that run reported no copy attempt rather
than a failure, the punkcheck staleness records having absorbed the earlier
failed attempts would be worth noting for G-094). Direct file copy from the
current root modules build (22:13, md5 b1226b3d) succeeded once the lock was
gone; bootsupport now matches root modules and _vfscommon.vfs (already fresh
via the earlier vfscommonupdate).
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Goal/Acceptance wording updated per user approval (verification runtime need
not be an official release). Upstream f10d91c2d3 fix confirmed merged and
present in TEMP_REFERENCE/tcl9; both G-039 defects addressed. Progress
entries: toolchain policy (zig-only for project integration), known-good 2024
zig build recipe determined and duplicated (zig-out90dup2026), 9.0.5
verification runtime built (tcl905 checkout, build905.zig: fresh-checkout
preconditions tclUuid.h + tclsh.exe.manifest, mingw_unicode_entry_point for
upstream's removed TCL_BROKEN_MAINARGS). Remaining: G-039 kill procedure on
the 9.0.5 runtime.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Content-identical rename (flip edits landed in the previous commit); GOALS.md
entry removed and the summary record (amended *** acceptance) appended to
GOALS-archive.md per the achieved flip workflow. Rides along: CHANGELOG.md
gains the required [0.17.1] entry matching the punkproject.toml bump from the
previous commit (punk::path 0.4.0 *** pathglob + separable lattice; runtests
targeting rework).
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
In-place closeout edits ahead of the archive move (per the goals/AGENTS.md
pure-rename discipline): detail-file Status flipped to achieved 2026-07-20
(all amended acceptance clauses verified - see the detail file's Progress
record), the console-attachment finding pushed to live G-061's Notes as part
of the archive reference sweep, and punkproject.toml patch-bumped 0.17.0 ->
0.17.1 for the punk::path 0.4.0 pathglob addition shipping in kit payloads
(user-directed). goals_lint transiently red until the archive-move commit.
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules + bootsupport + vfscommonupdate after the punk::path ***
source changes: path-0.3.0.tm -> path-0.4.0.tm snapshots in
src/bootsupport/modules and src/vfs/_vfscommon.vfs. The runtests parent
resolves punk::path from bootsupport - the refreshed snapshot is what enables
*** targeting at the runner discovery layer (discovery.tcl requires 0.4.0-).
Known ride-along not included: the bootsupport templates-0.2.0.tm modpod copy
failed to refresh ('invalid argument' - destination held open, likely a
running shell's zipfs mount; the stale copy predates this session) - reported
separately.
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com