The Tk opt-in census surfaced that the full suite cannot run unattended in
the batch/suite-built shell: winDialog.test (72 cases) and winMsgbox.test (19)
pop real OS dialogs whose message-injection automation does not drive them
here, so each blocks waiting on a human. The first attempt hung there and the
engine correctly reported no-totals/fail.
Adds a dedicated file-exclusion mechanism: tools/test_gate.tcl gains -notfiles
(a Tcl list of test-file globs passed to the driver as one -notfile list
value - a flat -testargs cannot carry a multi-file list through the option
chain, since -notfile takes a single list arg), and build905.zig gains a
per-library -Dtestnotfiles-<lib> knob defaulting to each LibSuite's
default_notfiles. tk defaults to excluding winDialog.test + winMsgbox.test so
its census completes hands-off; -Dtestnotfiles-tk="" re-includes them for a
manual interactive run. The exclusion is recorded in the evidence summary
(notfiles key). Empty for every other library (no behaviour change).
Verified: tk census now completes unattended (9865 run / 8127 passed / 1711
skipped / 27 failed, result pass; log shows winDialog/winMsgbox in the driver
skip list); thread gate still PASS with notfiles {} recorded.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The external libraries the suite builds and ships now run their own
testsuites under the suite-built shell as named recipe steps - evidence for
the exact zig-built combinations nobody upstream tests.
tools/test_gate.tcl generalized into the shared engine: -mode gate|record
(gate = parsed totals diffed against the tracked dispositioned baseline,
the core-gate mechanism; record = run must complete, failures recorded not
fatal), -driver selection (tcllib-family trees run via their own
support/devel/all.tcl - sak's underlying driver, standard aggregate totals,
per-file child interps), -summaryfile/-library line-record evidence
summaries for the G-103 artifact-metadata consumer (shape documented in the
goal detail file), file-error evidence capture (@+ blocks, runAllTests
error-exit sections). A run with no parseable totals FAILS the step in
every mode - infrastructure breakage must never masquerade as recorded
results. Core gate semantics unchanged; the core gate step now also writes
out/testreports/tclcore.summary.
build905.zig: steps test-thread test-tclvfs test-tcllib test-tklib test-tk
+ composite test-libraries (tk excluded - opt-in: interactive desktop, maps
windows, tens of minutes; intended before publishing bi-family artifacts).
Per-library -Dtestpolicy-<lib>=gate|record|skip and -Dtestargs-<lib>
invocation overrides - no recipe edits needed. Baselines staged in both
flows (suite.tcl item list + bootstrap recipe_items).
suite.tcl: test action takes -steps (default test-gate) and a -zigargs
passthrough (both actions); passes -j1 so combined test invocations
serialize (zig runs independent steps concurrently; thread's suite is
timing-sensitive).
Census results (suite tclsh90s.exe 9.0.5, zig 0.16.0): thread 143/0 failed,
EMPTY baseline, GATE PASS x3 identical consecutive runs; tclvfs 51/7
failed, all dispositioned (3x tcl9 glob-nomatch semantics through vfs
handlers, 4x dead-FTP network tests), GATE PASS x3 identical; tcllib WITH
tcllibc accelerators engaged (E tcllibc markers, crc32-critcl-* variants
running) RECORDED 62328/54 failed; tklib RECORDED 796/18 failed (widgetPlus
drift under Tk 9). No-totals failure path verified in both modes.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Found by G-107's first library-test census: build_tclthread.zig compiled
thread trunk 3.0.7 sources with -DPACKAGE_VERSION="3.0.1", so the dll
self-reported the wrong version, and the pkgIndex declared only capital-T
Thread 3.0.1 - the thread testsuite's 'package require -exact thread 3.0.7'
could never load the package (nothing previously load-tested thread at all).
The version now derives from the tree's AC_INIT (new build_common helpers
acInitVersion/stripChars) and flows into every version-derived name: dll
tcl9thread<nodots>.dll, install dir lib/thread<version>, PACKAGE_VERSION/
PACKAGE_STRING defines, rc resource fields, and a pkgIndex declaring BOTH
'Thread' and 'thread' (threadCmd.c provides both; the testsuite requires
lowercase, existing punkshell consumers the capitalized name). Dead
zip-related consts riding the stale version removed.
Note for the next kit/vfs refresh: the punk905 kit payload
(src/vfs/punk9wintk905.vfs/lib_tcl9/thread3.0.1/) still carries the old
self-consistent 3.0.1-stamped copy - refresh to the derived naming then.
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
Root cause of the punk86-kit runtests failure: a punk-kit interpreter's
boot pre-registers its kit-stamped package versions, and an unversioned
require satisfiable by such a registration never fires package unknown -
the freshly-added bootsupport tm path is never scanned. The old kit's
punk::args 0.1.0 won the require, then the versioned punk::path 0.4.0-
pulled a modern module whose load-time argdoc needs punk::args::define:
invalid command name.
Floors added: punk::args 0.12- (runtests.tcl toplevel), punk::lib
0.5.1- (both 8.6 lpop guards; punk::path 0.4.0- already floored in
discovery.tcl). Feature-era minimums, not latest pins - their purpose is
rejecting fossils so package unknown resolves the bootsupport copy.
Verified: the floors alone resurrect even the OLD fossilized punk86 kit
(discover-only + a 35/35 suite run); native 9 and 8.6 unaffected.
concurrency.test child preamble floors its punkcheck require (0.6-):
kit-hosted children boot with kit-stamped punkcheck PRELOADED, and a
stale kit (pre-vfscommonupdate _vfscommon) made children fail on
'invalid command name punkcheck:🔒:acquire' - the floor turns that
into a loud version-conflict in the child log.
src/tests/AGENTS.md records the floor rationale and the kit-hosted
child-suite requirement (vfscommonupdate-current kit content).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The remaining pre-policy punkshell-own bin utilities take the punk- prefix
(bin/AGENTS.md policy, G-096); external-tool wrappers (dtplite/sdx/kettle)
and getpunk stay unprefixed. No behaviour changes ride along.
- runtime scriptset: sources/toml renamed (src/scriptapps/bin/punk-runtime.*),
the eight ps1 usage/guidance messages now say punk-runtime.cmd, the bash
payload's filename-derivation comment example updated; REWRAPPED ->
bin/punk-runtime.cmd (checkfile clean) with the .ps1 twin regenerated as a
byte-copy. The roundtrip + checkfile pins retarget the new names and pass.
- tclargs + bits: sources/tomls renamed; bin artifacts moved BYTE-FAITHFULLY
(git mv, no rewrap): a pre-rename drift check showed both carry
pre-template-refresh wraps (477-byte delta = the template's 2025
wmic-deprecation timestamp fix; runtime was in sync). Regenerating them is
a behaviour change and is deliberately not smuggled into the rename -
recorded in the goal. Fresh .ps1 twins cut from the current .cmds; stale
untracked bits.bat/bits.ps1/tclargs.ps1/runtime.ps1 removed.
- selfsign experiments: SELFSIGN.PS1 -> punk-selfsign.ps1 (case normalized),
wrap toml + cert-create script renamed; the four untracked bin experiment
scripts renamed on disk; the exported .cer is not a script and keeps its
name.
- runtimebash_wsl.test: functional staged-filename sites updated (bash
./punk-runtime.bash; solo-fixture cp) along with comments.
- Docs: bin/AGENTS.md (examples, policy paragraph records the sweep, runtime
contract section, pin pointer corrected to runtimecmd_roundtrip.test),
src/scriptapps/AGENTS.md, root AGENTS.md, README.md, src/README.md,
untracked bin/runtime/README.md, G-060 reference, libunknown comment (src
copy; root modules/ + bootsupport copies catch up on their re-vendor
cycles).
Suites green: scriptwrap + binscripts 26 run / 25 passed / 1 constraint-skip
/ 0 failed - the roundtrip pin passes against the renamed artifact.
Discovered and recorded for user decision (goal Progress): the project
LAYOUT stores ship stale utility copies - runtime.cmd (2025-era payload) and
getzig.cmd (the G-096 rename missed this channel) - so generated projects
still receive old-named utilities; folding the layout channel into this
goal's scope vs a layout-sync mechanism is flagged.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The two child-spawning tests (two-writers, lock-holder) proceed on the
children's done-marker files, but a just-finished child can still hold
its redirected stdout log open for a beat after writing the marker - on
Windows the -cleanup tree delete then hits 'permission denied'
(observed as a ~1-in-3 flake under the slower Tcl 8.6 interp, exposed
by the new native-8.6 runtests support; same race existed under Tcl 9).
cleanup_workspace retries the delete briefly (10s deadline) instead of
flaking. 8/8 consecutive clean runs under 8.6.17 post-fix; Tcl 9.0.3
punkcheck subtree 84/84.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The runtests toplevel guard loads the bootsupport punk::lib snapshot -
this re-vendor puts the parity-fixed compat family there (the
testinterp guard already resolved the dev module via prefer-latest).
punkproject.toml 0.17.4 + CHANGELOG entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The validated compat family is brought across for the harness: guarded
'package require punk::lib' when ::lpop is absent, at both boot levels -
the toplevel two-stage boot (right after punk::args, whose parse needs
lpop at runtests.tcl's own argument parsing) and the singleproc
testinterp (before the shellrun preload, whose runx parses via
punk::args::parse). No-ops on Tcl 8.7+/9: -discover-only stays ~0.35s.
Native 8.6.17 verification: -discover-only works; punkcheck subtree
84/84, punk/lib subtree 43/43+1 gated skip, runner discovery suite
22/22, and a multiproc (-singleproc 0) probe 49/49.
Tcl 9.0.3 regression per the src/tests/AGENTS.md runner-change
contract: full suite in both modes with -report json,
runtests_parity.tcl reports PARITY: ok (files=96 total=1064
passed=1047 skipped=16 failed=1 - the sole failure is the documented
pre-existing exec-14.3 baseline).
src/tests/AGENTS.md records the supported-interpreter change and the
still-broken punk86-kit runtests route (kit/dev module skew - use a
native 8.6 tclsh for 8.6 legs).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Reviewed against the real 8.7/9 lpop via a 24-case differential (results,
final list state, error messages, errorcodes) - the compat proc was
correct on every success path; all divergences were error-path:
- out-of-range errors said 'tcl_lpop index ...' with no errorcode; now
the builtin's exact message and {TCL VALUE INDEX OUTOFRANGE}
- variable-access failures named the internal upvar link variable and
flattened detail (missing array element misreported as 'no such
variable'; unset var lost its TCL LOOKUP errorcode). Fixed by probing
with a plain read in the caller's frame BEFORE creating the upvar
link - through a link, or once a link merely exists, Tcl downgrades
the error class.
Finding: the assumed 8.6 divergence does not exist - 8.6's core index
parser already accepts TIP-176 M+N arithmetic, so compat::lpop now has
zero known divergence from the builtin (doctools note corrected).
compat.test extended (3 -> 10 tests): a differential parity matrix that
runs wherever the builtin exists (self-updating pin against future core
changes), static pins for values/errors/errorcodes that also run under
8.6 where no builtin exists, an unconditional M+N arithmetic pin, and
an 8.6-only pin that punk::lib installs lpop as the compat alias.
Green under Tcl 9.0.3 (9 pass/1 gated skip) and native 8.6.17
(9 pass/1 gated skip).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The five decorative 'echo --Installing package X--' addSystemCommand steps
(2024-era) spawned 'echo' as a program - a cmd BUILTIN that only resolved when
a coreutils echo.exe happened to be on PATH. In the PATH-scrubbed bootstrap
environment the spawns failed and took the tm installs, install-libraries and
(transitively) make-zipfs down with them - the reason the zip-wrapped shells
never landed in scrubbed composite runs while every package step was green.
zig's own step reporting makes the banners redundant.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Per the G-095 note, the advisory protocol is only effective once all
writers carry it - bootsupport re-vendored immediately after landing.
Verification under 0.6.0: 'make.tcl modules' + full 'make.tcl project'
exit 0 with zero lock timeouts, zero tripwire warnings, no spurious
recopies, all kit installs skip 'no change detected', and no
.punkcheck.lock / .punkcheck.tmp.* leftovers anywhere in the tree.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Saves are write-temp-then-atomic-rename with bounded retry for Windows
sharing violations; load_records_from_file retries transient open
denials during a writer's replace window (parse errors stay strict -
they mean real corruption). Readers gain torn-read immunity with no
reader-side protocol.
New punkcheck::lock namespace (PUNKARGS-documented): advisory sibling
lockfile <punkcheckfile>.lock via open {WRONLY CREAT EXCL}, contents
naming holder pid/host/installer/timestamp, channel held open for the
duration, in-process reference-counted re-acquisition (sequential
make.tcl installers over one root must not self-deadlock). start_event
acquires; event end / installtrack destroy releases; flushes and
chokepoint saves outside an event take a transient lock. Contention
retries with backoff to -timeout (env PUNKCHECK_LOCK_TIMEOUT, default
15s) then errors naming the holder; stale locks break on provably-dead
holder pid (twapi process_exists / kill -0, capability-gated) or age
(-staleage / PUNKCHECK_LOCK_STALEAGE, default 300s).
Deferred flushes merge own records (INSTALLER by -name, touched
FILEINFO by -targets) into freshly-loaded file state under the lock
instead of wholesale overwrite; an mtime/size tripwire warns when a
non-protocol writer (e.g. older vendored punkcheck) touched the file
between load and save.
Duplicate-INSTALLER recovery: clean actionable error when stdin is
non-interactive (punkcheck::lib::stdin_is_interactive - strict twapi
GetConsoleMode on the real stdin handle on Windows, -inputmode probe /
test -t 0 on unix); the interactive prompt gains the synced-targets
deletion-wedge caveat. default_excludefiletail_core adds .punkcheck.*
so protocol siblings are never installable content.
Consumers verified without edits: cli and five make.tcl sites end their
events (lock released at end); make.tcl's vfs/bin kit flows destroy
their installers on every path (destructor releases).
New concurrency.test (6 tests): two child installer processes with a
polling reader (no parse errors, both installers survive, no duplicate
INSTALLERs, no lock/tmp leftovers), lock timeout naming the holder then
success after release, dead-pid and age stale-breaks against planted
lockfiles, non-interactive duplicate-INSTALLER error via pipe-stdin
child, protocol-sibling exclusion pin.
Matrix: Windows Tcl 9.0.3 84/84 (runtests), Windows Tcl 8.6.17 84/84
(direct tcltest drive - the runtests harness itself needs lpop under
native 8.6), linux WSL tclsh 8.6.14 84/84 (native-FS staged run).
punk/mix subtree unaffected (150 pass / 1 known constraint-skip).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Three deltas surfaced by the PATH-scrubbed clean-checkout demonstration:
- build.zig: default-entry re-export of build905.zig's build so the documented
plain 'zig build stage|bootstrap' works from the tracked suite dir (the
recipe keeps its versioned filename; staged flows still invoke it via
--build-file).
- critcl_zig.config + recipe: settings move under an EXPLICIT target
(win32-x86_64-zig) and the tcllibc step passes -target win32-x86_64-zig.
critcl otherwise chooses its build target by probing PATH for compilers -
with a gcc visible the config defaults engaged (why G-098's flow worked),
but the scrubbed environment fell back to critcl's builtin msvc 'cl'
target and all 25 accelerator modules failed with "couldn't execute cl".
Verified green in BOTH environments (scrubbed and normal PATH).
- build905.zig comptime gate: the stale 0.13-dev minimum becomes the actual
suite pin (0.16.0) with a message pointing at punk-getzig and the README
(acceptance: the recipe records the zig version it is written against).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
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
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
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
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
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
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
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
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
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
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
User-approved contract amendment replacing the day-1 file-relpath filter: one
directory-oriented pathglob semantics at every layer, with the ergonomics gap
closed in the syntax itself.
punk::path 0.4.0:
- *** as a whole segment matches ZERO or more segments (join-aware regex in
pathglob_as_re: an adjacent separator is absorbed into an optional group),
so X/*** = X and everything below - the subtree spelling; ***/f.txt matches
at any depth including the root.
- include separability fix: an exact or single-segment-glob full match no
longer sets allbelow (the deep walk previously dragged the whole subtree in
for X and X/* patterns; the zipfs walk was already separable).
- exclude separability fix (new exclude_state classifier, both walks): only
**|***-tail patterns prune the matched subtree; other matches exclude just
that directory's files - the **/_aside vs **/_aside/** argdoc distinction is
now real. Dead _path_matches_any removed.
- legacy bare-* include collapse removed (a * in -include-paths is the
one-below lattice form, not a match-everything alias; no caller used it).
- globmatchpath default-nocase driveletter exception rewritten as a direct
regex-head rewrite (the regex-text file-split broke on c:/***'s glued group
and accepted non-alpha drives).
- path.test +5 lattice/*** pins (40 total).
runtests.tcl:
- -include-paths/-exclude-paths pass through to treefilenames unchanged;
argdocs teach the separable X | X/* | X/** | X/*** lattice; directory and
file-name axes independent (tails); single-file targeting = exact dir
pattern + file tail.
- -serial-paths reconciled to the same directory-of-file reading (default now
modules/punk/console/*** modules/opunk/console/*** via
runtests_discovery::dir_matches_any) - the pre-existing file-path serial
matching was the other same-option-different-referent divergence.
- per-pattern zero-match stderr advisory (the X/**-for-subtree foot-gun points
at X/***).
- json report emitter: whitespace-padded entier-looking values now take the
quoted-escaped path ('string is entier -strict' accepts surrounding
whitespace - a failed test's "0\n" result_was embedded a raw newline and
truncated the parseable report line).
- testsupport/discovery.tcl now a thin passthrough (requires punk::path
0.4.0-); pathdiscovery.test rewritten to the directory-semantics contract
(22 tests incl. the X/** zero-match advisory characterization); AGENTS.md
targeting guidance swept to /*** across src/tests and src/modules/opunk.
Verification (native tclsh 9.0.3, piped, serialized): 45-probe matrix, path
suite 40/40, runner suite 22/22; vs the pre-G-093 baseline the default
discovery FILE SET differs by exactly the added runner suite and result
parity only by the five new path tests (+ that suite); mode parity -jobs 16
vs singleproc: PARITY ok (94/1037/failed=1 exec-14.3). Goal contract amended
in the detail file; full record there.
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Root cause (recorded in the goal file): punk::path::treefilenames matches
-include-paths against the DIRECTORY containing files, and its documented
X/** boundary semantics exclude files directly in X - so suites keeping
.test files at the subtree root (scriptwrap, binscripts, punkexe) were
silently missed by X/** targeting: the G-092 four-pattern (2/13 files) and
repeated-flag (zero files) failures. punk::args -multiple accumulation
probed healthy - repeated flags and a single space-separated value reach
discovery identically; no punk change was needed or made.
runtests.tcl now filters the tailbase-relative FILE paths after an
unrestricted walk (new testsupport/discovery.tcl: globmatchpath,
any-include-match, exclusion wins): X/** includes files directly in X, an
exact relative path targets a single file, a bare directory path matches
nothing (append /**). -exclude-paths exposed (same syntax and accumulation,
exclusion wins over inclusion). -discover-only prints the discovered list
plus a RUNTESTS_FILES tcl-list line and exits before any run machinery -
subsecond via a two-stage boot (discovery phase loads only punk::args +
punk::path; punk/Thread/shellrun/punk::tcltestrun and the testinterp/child
path assembly load after the exit).
New regression suite runner/testsuites/discovery/pathdiscovery.test
(23 tests: pure filter, fixture-tree walk+filter, end-to-end -discover-only
children including both G-092 characterization forms; ~7s wall,
parallel-safe). src/tests/AGENTS.md targeting wording reconciled; new
src/tests/runner/AGENTS.md. G-093 index status proposed -> active
(user-directed).
Verification (native tclsh 9.0.3, piped Bash context): pre-change baseline
default -jobs 16 (93 files / 1010 tests / failed=1 exec-14.3 only) vs
post-change -jobs 16 with -exclude-paths runner/**: PARITY ok; post-change
default run differs from baseline only by the added suite (+23 passing);
mode parity -jobs 16 vs singleproc sequential: PARITY ok (94/1033/1).
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com