parse_testrun previously required a failing test's opening banner
'==== <name> <description> FAILED' to be one physical line: a description
with embedded newlines spans lines (single tcltest puts, ends-only trim),
the opener never matched, the closing banner was misread as an opener and
the parser wedged in failure-capture state - every later event including
the summary line was swallowed and the file degraded to
warn/missing-cleanupTests with no failure detail.
Now (G-161, settled on start-event anchoring + bounded banner buffering):
- '---- <name> start' lines (-verbose start - runtests.tcl always passes
it) track the current test name.
- A line '==== <name> ...' for the current test that does not end
' FAILED' opens a banner-continuation stage (exact prefix compare, no
glob), buffered until the ' FAILED'-terminated line completes the
banner; recognisable event lines (took/PASSED/SKIPPED/start/summary) or
a 100-line bound abandon capture and reprocess the line normally, and a
stray '==== Contents of test case:' completes the banner instead of
wedging.
- Streams without start events, and every single-line parse path
(including the emulated-banner confounder heuristics), behave exactly
as before - pinned by the new characterization suite.
Also fixes result_expected capture (G-161 acceptance surface): the
'---- Result should have been' opener always arrives while the
result_was capture is active, and the active-capture reset branch fell
through past the opener elseif - result_expected was absent from every
FAILED report (verified in the current full-suite baselines) and the
expected-value lines leaked into test_body. The active branch now
transitions result_was -> result_expected directly.
New synthetic characterization suite
src/tests/runner/testsuites/parser/parsetestrun.test (6 tests: multi-line
fidelity incl summary flow, single-line regression shape, multi-line
ERROR capture, anchored false-open abandonment, historic confounder pin,
no-start-events fallback pin) green on tclsh90 (9.0.3) and native tclsh
8.6. Streams mirror real tcltest emission (verified against a live
tcltest 2.5 capture). E2E fixture suite + bootsupport promotion follow in
this arc.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
get_size_using_tput invoked tput once with two capnames ('tput lines cols').
Multi-capname support varies by tput implementation: ncurses >= 6.1 and the
BSD tputs emit one value per capname, but older ncurses treats the second
capname as an (ignored) parameter of the first and emits only the first
value - lassign then set cols to "" and the mechanism returned
'columns {} rows <n>' without erroring. Because size_via_query_mechanisms
caches mechanisms fastest-first after a first-call timing probe, and a tput
fork outpaces the ANSI cursor round-trips on unix, the malformed tput result
won every call after the first (first call returns the probe pass's
cursorrestore result - hence 'worked first time' on WSL, then
'columns {} rows 66' and dependent failures e.g punk::ansi::example).
- get_size_using_tput: autodetect multi-capname support by result shape on
first use, cached per tput path (capable tputs stay single-fork;
single-cap-only tputs settle into two forks); results validated as
positive integers, else the mechanism errors and drops out.
- new get_size_using_sttysize mechanism: 'stty size' on the input tty -
single fork, fixed '<rows> <cols>' output shape (GNU/busybox/BSD),
slotted ahead of tput in the probe order; errors cleanly on non-tty input.
- size_via_query_mechanisms hardened with size_result_valid: mechanism
results must be well-formed {columns <int> rows <int>} dicts in the probe
pass, vt52 branch and cached loop - covers this regression class and the
ANSI mechanisms' {columns {} rows {}} timeout results (previously a
no-responder tty's first get_size returned that malformed dict).
- get_size_using_chanconfigure: note that tcl 9.0.2 unix tty channels expose
no -winsize (windows console channels do) and stacked/reflected stdout
masks the underlying tty's options.
Verified on WSL pty (266x66): sttysize/tput (multi-cap and forced two-fork
paths) all return columns 266 rows 66; get_size x3 consistent (pre-fix same
harness: first call malformed, user-reported columns {} thereafter). Windows
piped smoke: sttysize errors cleanly, tput fallback accepted, get_size
consistent 80x24 defaults, no errors. make.tcl modules mint OK.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Promotes the minted shellfilter 0.2.5 (transchan clear/flush fixes - see prior
commit) into src/vfs/_vfscommon.vfs for the next bake, replacing 0.2.4.
Also carries the punk::mix::templates modpod refresh from the mint's
thin-layout sync: the punk.project layout's bootsupport include_modules.config
payload catches up to the commandstack manifest repoint (src/vendormodules ->
modules, G-160 follow-through) plus the modpod container restamp.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
tee_to_pipe declared the transchan 'clear' op; the Tcl core delivers 'clear'
before every write when declared (the G-145 defect class - see
goals/archive/G-145-piped-usage-ansi-remnants.md) and the handler discarded
o_encbuf, the held partial multi-byte character. The following chunk then began
with orphan continuation bytes and could never decode (the tail-backoff only
trims the end), so whole chunks accumulated in o_encbuf and successive clears
discarded them - eating contiguous multi-KB ranges of multibyte-dense output on
the unix repl console stack: 'i <cmd>' help tables displayed with missing
paragraphs, fused mid-word seam lines, or truncated bottom rows (WSL and native
linux ttys; windows unaffected). Isolation repro: 393/600 lines lost with
clear-per-write vs 0/600 without.
- tee_to_pipe: 'clear' no longer declared in initialize, so the core never
delivers it (same shape as the G-145 fix in ::punkboot::ansistrip); the
method is kept as a state-preserving no-op with a warning comment.
- flush repaired in tee_to_pipe, tee_to_log and logonly: all three referenced
an undeclared o_buffered variable (copy-paste from the o_buffered-bearing
ansiwrap/ansistrip classes) and threw on every invocation. Each now holds an
undecodable partial char in o_encbuf for the next write and emits any
decodable remainder per its class semantics.
- Verified: transform isolation harnesses clean at all chunk sizes with
clear-per-write; WSL end-to-end (linux kit visitor mode on a script(1) pty)
shows all previously-missing define/list table content present;
'make.tcl modules' mint OK.
- shellfilter-buildversion 0.2.4 -> 0.2.5; punkproject 0.49.3 -> 0.49.4 with
CHANGELOG entry; G-090 Context records the finding as audit evidence (no
characterization tests exist yet for these transforms - G-090 scope).
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport: commandstack-0.6.0.tm now pulled from minted root
modules per the repointed manifest; superseded bootsupport copies
removed - packagepreference-0.2.0 auto-pruned (punkcheck DELETE),
commandstack-0.3/0.4 removed by hand (their punkcheck lineage names the
departed src/vendormodules source, so the prune conservatively left
them; the manifest is non-glob single-version intent).
make.tcl modules sync: layout manifest copies (basic, project-0.1) and
the templates-modpod copy pick up the repointed commandstack entry.
make.tcl vfscommonupdate: _vfscommon.vfs modules commandstack
0.4.1 -> 0.6.0, punk/packagepreference 0.2.0 -> 0.2.1 (next bake
carries the fixed pair into kits). Stale .punkcheck.lock from the
completed run removed (dead pid 128656, not committed).
Verified post-promotion: commandstack suite 33/33 on punk86,
packagepreference 6/6 on tclsh90 (bootsupport snapshots on the
runtests tm path).
Claude-Session: https://claude.ai/code/session_01TNn3C58Cpekt3CsZNLCqvR
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Per the repo LF preference (edit-touched file; fossil CRLF gate flagged
it on the manifest-repoint checkin).
Claude-Session: https://claude.ai/code/session_01TNn3C58Cpekt3CsZNLCqvR
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
commandstack is first-party (src/modules source, minted to root modules/
since the module left vendormodules) - the manifest still pointed at
src/vendormodules, which carries no commandstack-*.tm, so bootsupport
was frozen at the stale 0.3/0.4 copies. Repoint to base `modules` (the
packagepreference pattern) in include_modules.config and the tclpackages
toml record so `make.tcl bootsupport` promotes the minted 0.6.0.
Layout manifest copies sync on the next make.tcl modules run.
Claude-Session: https://claude.ai/code/session_01TNn3C58Cpekt3CsZNLCqvR
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
commandstack 0.6.0:
- tokenid unique+monotonic per (renamer,command): counter increments the
real namespace variable (was an apply-local copy stuck at 1). Same-
renamer re-renames chain through the full stack, are removable by
exact token, and a third rename no longer collides on the parked name.
- get_next_command resolves via a maintained token->implementation dict
(O(1) dispatch, no lsearch stack scan; parked stacks keep dispatching).
- get_IMPLEMENTOR: ::tcl::info::cmdtype qualified in guard and call -
the builtin classification branch is reachable (undetermined on 8.6).
- debug validates its argument with a clean error naming on_off.
- Channel discipline: informational warnings debug-gated on stderr,
stray bare 'puts stderr' removed, errors stay errors.
- Records carry trailing did_rename 0|1 (leading token/renamer key order
contract unchanged); no-rename returns {implementation {} did_rename 0}.
- rename_command errors when -renamer appears in a non-leading position.
- get_stack raw-key-first (Rename_stack-parked stacks retrievable);
Rename_stack returns 1/0; Delete_stack errors while records are live.
- New delegation helper commandstack::next (PUNKARGS-documented, in help).
- known_renamers defaults reconciled to the vendored packages' actual
renamer strings (packagetrace packagesuppress).
punk::packagepreference 0.2.1: install re-install guard reads record key
'renamer' (was 'rename' - a second install threw instead of returning 0).
Tests: the five _GAP_ defect pins flipped to fixed-behaviour pins; new
pins for did_rename/key-order + token-map consistency, silent cycle with
debug off, -renamer misplacement, commandstack::next delegation incl
caller context, Rename_stack/get_stack parking, Delete_stack guard;
new packagepreference installguard.test (double-install returns 0,
uninstall/re-install cycle with fresh tokenid). commandstack suite 33/33,
packagepreference 6/6 - green on tclsh90 (9.0.3) and punk86 (8.6).
Live punk91 src smoke: packagepreference/auto_execok/cd renames working.
Claude-Session: https://claude.ai/code/session_01TNn3C58Cpekt3CsZNLCqvR
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Module (src/modules/commandstack-999999.0a1.0.tm, 0.4.1 -> 0.5.0):
- commandstack::help now returns a real dependency-free API overview (was
an empty string): rename/remove workflow, COMMANDSTACKNEXT delegation
contract, inspection commands, in-tree users.
- PUNKARGS documentation blocks added for every API proc (help, debug,
get_stack, get_next_command, basecall, rename_command, remove_rename,
show_stack, Delete_stack, Rename_stack, util::get_IMPLEMENTOR,
lib::splitx, lib::split_body), registered lazily via
::punk::args::register::NAMESPACES - no punk::args dependency added.
Tests (new src/tests/modules/commandstack/testsuites/commandstack/commandstack.test,
29 tests, green on tclsh90 9.0.3 + punk86 8.6):
- usage-driven characterisation of the behaviours in-tree consumers rely on
(punk::packagepreference, packagetrace, packagesuppress, punk auto_execok,
punk::nav::fs cd): record shape/key-order contract, implementation {} as
the no-rename signal, COMMANDSTACKNEXT/COMMANDSTACKNEXT_ORIGINAL
delegation, multi-renamer stacking with removal in any order, builtin
renames, remove_rename argument forms, show_stack fallback render,
get_IMPLEMENTOR/split_body/splitx, help, lazy punk::args registration.
- known defects pinned as _GAP_ tests: per-renamer tokenid stuck at 1
(apply-local counter var) so same-renamer re-renames stack duplicate
tokens whose dispatch bypasses intermediate layers, and a third rename
collides on the parked-implementation name; get_IMPLEMENTOR builtin
branch unreachable (unqualified info commands pattern inside
commandstack::util); Delete_stack under a live rename self-delegates to
recursion; stray bare puts stderr writes literal stderr to stdout.
- behavioural tests run in fresh child interps (module sourced by path,
::puts shim captures module warnings for assertion).
Docs:
- src/tests/AGENTS.md: new contract - test descriptions must be single
content line (multi-line descriptions make tcltest failure banners
multi-line; punk::tcltestrun parser then swallows all later events
including the summary line - discovered authoring this suite).
- src/tests/modules/AGENTS.md: commandstack child index entry.
- punkproject.toml 0.49.2 + CHANGELOG entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The bin-folder launch shim sourced main.tcl from ../src/_build/<kit>.vfs
trees - the pre-G-155 kit-assembly workdir. Since the src/_bake rename
those paths resolve only to the stale leftover _build trees, so the shim
would silently launch outdated payloads. Nothing references or deploys
it (no punk_wrap.toml scriptset, no bin/punk.tcl copy; bin/punk.ps1 is
an unrelated multishell polyglot), and its fauxlink fallback comments
predate current vfs practice. Removed at user direction rather than
retargeted to src/_bake.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
register_all_tm (deep .tm discovery at every namespace depth, used by
'dev lib.search') knew only the pre-G-155 _build workdir name: the
filesystem directory walk skipped _build dirs and the tm-file filter
dropped */_build/* paths, but the renamed staging area <srcdir>/_mint
(and the src/_bake kit workdir) were scanned - loose staged .tm files
were registered as junk modules (measured against src/modules: 9 junk
registrations - _mint::gridplus, punk::mix::_mint::templates,
test::punk::_mint::* etc).
Both sites now skip _build, _mint and _bake (the tm-file filter also
guards the zipfs whole-tree listing branch); register_all_tm help text
updated. Manual-version bump mechanics applied per src/modules/AGENTS.md
(file rename, Meta line, manpage_begin, provide block, version-history
entry).
punkshell 0.49.1 (punkproject.toml + CHANGELOG.md - libunknown ships in
kits; the tcltestrun 0.3.1 test-tooling fix from 1eae7260 is recorded in
the same changelog entry).
Verified: probe on old vs new module - 0.2.3 registers the 9 junk
_mint::* packages, 0.2.4 registers 0 with real modules intact (textblock
sanity, registered 107 -> 98 = exactly the junk); runtests
discovery.test + shadowing.test 23/23.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules + bootsupport + vfscommonupdate outputs for the tcltestrun
0.3.1 fix (source commit 1eae7260): src/bootsupport/modules and
src/vfs/_vfscommon.vfs/modules move from tcltestrun-0.3.0 to tcltestrun-0.3.1
(superseded copies pruned with punkcheck DELETE records), and the fixed
modules/test/runtestmodules.tcl is synced into _vfscommon.vfs.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
tm_path_additional_ifneeded (punk::tcltestrun) and its inline equivalent in
src/modules/test/runtestmodules.tcl called punk::path::subfolders with
-exclude {**/_build/** **/_build} - the G-155 _build -> _mint staging rename
never reached these call sites, so staged pods in <srcdir>/_mint were being
registered as bogus modules (e.g punk::mix::_mint::templates 0.2.0; measured
99 leaked _mint subfolder entries under src/modules across the two staging
trees src/modules/_mint + src/modules/punk/mix/_mint).
Both call sites now use the full option name and the pruning ***-tail form:
-exclude-paths {**/_build/*** **/_mint/***} (_build kept for legacy
checkouts). The ***-tail form prunes descent per punk::path 0.5.0, and
kit-baked punk::path 0.4.0 already accepts both the literal -exclude-paths
name and *** segments (G-093), so kit-child shadowing scenarios stay
compatible.
Verified: direct probe shows 0 _mint/_build subfolder entries and only
legitimate pods registered; runtests.tcl path.test 67/67 with no _mint
registrations in the harness startup.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules + bootsupport + vfscommonupdate outputs for the path 0.5.0
arc (source commits ed17fb6c, 4d481e42): src/bootsupport/modules and
src/vfs/_vfscommon.vfs/modules move from path-0.4.0 to path-0.5.0
(superseded copies pruned with punkcheck DELETE records; promoted copies
byte-identical to the minted module).
Note: the vfscommonupdate PROVENANCE-WARNING emitted during this run
referred to the preceding bootsupport step's own outputs - batched here
per the build-outputs commit convention.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Continuation lines of the -nocase option help now carry the standard
2-extra-space indent used by argument -help blocks (per the
src/modules/AGENTS.md Procedure Documentation Template guide).
Indentation-only; render verified on punk91.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::path 0.5.0:
- subfolders1 REMOVED - no call sites repo-wide; subfolders is the reviewed implementation
- subfolders ***-tail -exclude-paths patterns now classify as pruning subtree rules: X/*** is handled as the equivalent pair {X/** X} - identical results (the *** descend test alone omits and prunes the boundary), walk no longer descends excluded subtrees (~250x measured on a 1110-dir excluded subtree); bare *** exclude short-circuits like bare **
- strip_prefixdepth fixed: called the nonexistent 'norm' since its 2024-08-12 copy from punk::repo::path_strip_prefixdepth (kettle::path::strip lineage) - now uses the textual punk::path::normjoin; depth-only no-content-compare contract kept; prefix-exhausts-path boundary still errors (zero-arg file join), characterised not changed
- missing punk::winpath dependency declared (normjoin calls is_dos_device_path on every input - errored in a minimal interp that required only punk::path)
- PUNKARGS consistency pass: *|**|***|? path glob syntax centralised in argdoc::PATHGLOB_SEGMENT_SYNTAX (tstr placeholder fragment) shared across pathglob_as_re/globmatchpath/subfolders/treefilenames help; new argdocs for pathglob_as_re, normjoin and strip_prefixdepth; globmatchpath summary corrected (*** added) and doctools [fun] markup removed from punk::args help; treefilenames no longer claims unsorted results (-sort and zipfs dispatch documented), -exclude-paths/-exclude-files/-include-paths typed -type list, tail globs documented as ordinary Tcl globs
- path.test 40->67: coverage for previously-untested in-use functions (relative, normjoin, pathtype, scriptlib_resolve, treefilenames_zipfs with zipfs mkzip/mount fixture) plus globmatchpath ?/-nocase variants, treefilenames -exclude-files and -sort order pins, subfolders ***-tail/pair-equivalence/guard/classifier pins, strip_prefixdepth characterisation
Docs/conventions:
- src/modules/AGENTS.md: PUNKARGS Procedure Documentation Template converted to the -& record-continuation layout; -& stated as preferred for new work (existing blocks may keep backslash continuations)
- punk::path argdoc blocks converted to the aligned -& layout
- src/modules/punk/AGENTS.md: shared glob-syntax fragment mechanism (flush-left authoring rule, resolved_def consumer caveat) + subfolders1 removal recorded
punkshell 0.49.0 (punkproject.toml + CHANGELOG.md entry).
Verified: path.test 67/67 under tclsh90; all 10 documented punk::path ids render clean on punk91 (tcl9) and punk86 (8.6); punk::LOC resolved_def consumer of treefilenames -exclude-paths intact.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Machine-generated propagation of the guarded punk::lib require that landed
in punkboot core with a5f60ce4: thin-layout sync copied the fix into the
punk::mix::templates modpod source (punkboot_core.tcl, punkboot/core.tcl),
and the templates-0.2.0.tm repack was promoted byte-identical to vfscommon
and bootsupport. The bootsupport copy was two repacks stale and also picks
up the G-032 thin-mains content (project_main.tcl, punk_main.tcl) already
delivered to vfscommon in 155157e3. Pack contents verified member-by-member
against the modpod source tree; only the two punkboot files differ from the
committed vfscommon copy.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Tcl 9 removed tilde expansion: kettle_call's lib-mode 'file mkdir ~/.kettle'
created a literal ./~/.kettle dir in the cwd - littering every tcl9-driven
'dev project.new' target via the kettledoc step (found during the modpod
checkout structure refresh). Home is now resolved explicitly ([file home]
on 8.7+/9, native ~ expansion on 8.6); no resolvable home skips the
optional dotfile config; the mkdir is catch-guarded. Same-shape local patch
in src/vendorlib/kettle1/app.tcl (kettle's own dotfile read silently
ignored ~/.kettle/config under tcl9), comment-marked for
reapply-on-vendor-upgrade.
Verified by scratch-cwd repro: kit cli 0.6.0 creates ./~ (TILDEDIR=1),
working-tree 0.6.1 does not (TILDEDIR=0), real HOME/.kettle used.
Propagated bootsupport + vfscommon (modules cli-0.6.1, lib kettle1).
No bake in this commit - the tree carries unrelated in-flight work, so
kits keep the litter behaviour until the next bake. Project-version
bullet left to fold into the pending 0.48.0 CHANGELOG entry.
Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl vfscommonupdate + modules ripple from the G-032 change-set
(driven with native Tcl903 per the recorded mkimg trap - kits assembled
archive-relative, no G-134 warnings): _vfscommon punkboot/core.tcl
regenerated from the 0.3.0 master; moduledoc::punkexe 0.3.0 -> 0.4.0 and
moduledoc::punkboot 0.1.0 -> 0.2.0 version renames; punk::mix templates
modpod repacked carrying the layout _config sweep (synced copies under
the #modpod-templates tree - punkcheck-managed, never hand-edited).
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The kit launch surface dogfoods punk::args. Boot core 0.2.1 -> 0.3.0:
new built-in 'help' subcommand + '-help' / '<subcommand> -help' render
tabled usage from the moduledoc::punkexe ids plus live registrations
(per-kit resolved_def clones (script)::punkexe.launcher/.launcherhelp);
unknown first arg naming no existing file (and no lib:* reference) is
refused with usage (stderr exit 1) instead of a silent script attempt;
buildinfo enforces its no-arguments contract through punk::args (pinned
one-liner + tabled usage, exit 2 unchanged). Registration extension
::punkboot::project_subcommand_info (summary/argsid/package/parse -
documented by moduledoc::punkboot 0.2.0): project subcommands appear in
help by registration alone and may opt arguments into declared parsing.
Carve-outs: tool-style kits keep help flags routed to their processor
(tomlish parity); tclsh intercepts a help flag only as sole argument
(stock dash parity); argsid-less registrations keep -help passthrough.
G-030 degradation doctrine: lazy guarded requires (normal boots never
load punk::args), PUNKBOOT_PLAIN=1 hook, plain-list fallback, rendering
degrades independently of parsing. 8.6 trap fixed en route: punk::args
choices-grid render needs punk::lib's lpop shim - guarded require added
(verified tabled help on metakit punk86).
moduledoc::punkexe 0.4.0: (script)::punkexe::help definition; top-level
refusal rule + help discovery; per-subcommand -help notes; buildinfo
rejection shape; passthrough-vs-parsed decision recorded.
Verified on zipfs (punk902z, punk91) and metakit (punk86) kits;
launcherhelp.test 22/22 (incl fake-thin-main registration harness +
metakit leg); punkexe subtree 140/136/4skip/0fail; full suite failures
(4) are pre-existing in untouched subsystems. Goal flipped achieved +
archive record + live-tier sweep (G-038 rewrite, pointers to G-077 and
G-089); detail-file move to goals/archive follows as a pure rename.
Layout _config trio + _vfscommon core seed hand-swept (byte-identical
to masters). GOALS.md staged as the G-032-removal hunk only - the
uncommitted G-159 draft entry is left to its author.
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Tar-era connection API removed from modpod (connect/disconnect/get,
system::connect_if_not/myname/myfullname - broken since the tarjar era, no
callers anywhere); is_valid_tm_version fixed (versionparts substitution
error); make_mountable_zip debug output removed (the undeclared ansistring
dependency made -offsettype file error under the module's declared deps;
stray ::last_header global gone); struct::set dependency dropped; module
greps tarjar-free. The load stub gains the unwrapped #modpod-<pkg>-<ver>
redirect: an extracted folder beside the .tm is sourced directly - loads
with neither zipfs nor vfs::zip available.
Re-vendored 0.1.6 through the established channels (modpod checkout mint ->
vendormodules -> bootsupport -> modules staging -> vfscommon). First modpod
testsuite at src/tests/modules/modpod/testsuites/modpod/roundtrip.test:
wrap/load round-trips - real-disk + zipfs module paths, both -offsettype
forms, unwrapped redirect, probe-discovered binary payload (no committed
binaries). Green: punk91 tcl9.1 kit 7/7, native tclsh90 7/7, punk86 8.6.17
6/7 (zipfs-container test skips on 8.6 - recorded per G-034).
G-111 activated at user request (activation overlap survey recorded);
per-defect dispositions, run evidence and tarjar-artifact assessment
proposals in goals/G-111-modpod-tidy-tests.md - artifact dispositions
await user confirmation. GOALS.md G-111 Scope version reference repaired
to glob form per goals-system v3 drift rule.
Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
shellspy/punk/script/shell report the missing package by subcommand name and
exit 1 instead of a raw package-require trace - found adopting the shared
core in the tomlish kits (app-tomlish only; proven there first, master
replay identical by diff). Layout _config/_vfscommon copies refreshed.
tomlish adoption itself is committed in its own fossil (bbc68a3f) - the
G-031 derived-project proof.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
project_main.tcl reborn as the heavily commented thin-main sample (1132-line
2025-vintage monolith retired): ==CUSTOMIZE== blocks for project_subcommands
and launch_defaults with worked tool-style examples, fauxlink/rename guidance,
boot-core do-not-fork note, opt-out story incl the collision rule. Layout
project-0.1 _config hand-swept (outside sync channels per the 0.43.0 lesson):
thin punk_main.tcl + sample + punkboot_core.tcl master, punkboot/core.tcl
seeded in the layout _vfscommon.vfs; templates modpod mirror synced by the
modules step. Boot-entry guidance sections added to src/vfs/README.md (repo
and layout voices) covering the recommended _config-behind-the-fauxlink path,
plain root main.tcl alternative, one-startup-script rule, _config inertness;
src/vfs/AGENTS.md refreshed (ownership split, collision gate, G-129
derivation now consolidated in the core).
E2E on a freshly generated punk.project project (punk902z src script recipe,
FOSSIL_HOME diverted, shallow c:/T dir): generation completes incl fossil
initial commit; the project boots through its own _config trio via the
sibling master (core 0.1.0); a 'demo' subcommand added by editing ONLY the
generated thin main at its customization points dispatches in all three
launch forms (explicit args, bare via noargs, unknown-first via
unknownfirst).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules/vfscommonupdate/bootsupport regeneration for increment 2:
_vfscommon.vfs/punkboot/core.tcl regenerated from the committed _config
master (every kit's merge now carries the boot core); layout copies of
src/make.tcl (basic, project-0.1, templates modpod source) pick up the
vfscommonupdate boot-core delivery step via the modules-step sync, with the
repacked punk::mix templates-0.2.0.tm promoted to _vfscommon and bootsupport.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk_main.tcl is now the thin project-owned main: publishes launch_args +
main_script, declares (empty) project_subcommands and launch_defaults at
==CUSTOMIZE== points, locates the boot core and sources it. Core candidates:
<vfsroot>/punkboot/core.tcl (in-kit via the _vfscommon merge), parent-dir
punkboot/core.tcl (nested app/main.tcl, undroidwish G-129), sibling
punkboot_core.tcl master (source-tree execution - the kitmountpoint
characterization shape). punkboot_core.tcl carries the boot machinery
extracted verbatim from the monolith; delta beyond extraction: contract
preamble with serviceable defaults, normscript from ::punkboot::main_script
instead of [info script], registration-model subcommand selection (project
additions merge in, built-ins cannot be shadowed, declared noargs/unknownfirst
defaults) with a dispatching default arm, ::punkboot::core_version 0.1.0.
make.tcl vfscommonupdate now regenerates _vfscommon.vfs/punkboot/core.tcl
from the _config master.
Parity evidence: full punkexe suite 110 pass / 0 fail against freshly baked
punk902z; kitmountpoint 4/4 across 8.6-backport / 32-bit-modern / 64-bit
runtimes incl the unattributed-mount stderr pin; registration model exercised
end-to-end via a scratch kit; 11-kit default bake with only known-baseline
warnings; punk86 (metakit/starkit, tcl 8.6.17) smoke green. cookfs branch
carried verbatim - no cookfs kit is currently mapped in mapvfs.toml to
exercise it (stale bin/punk9cook.exe is an old vintage, untouched).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules/bootsupport/vfscommonupdate regeneration for increment 1:
utils-0.7.0.tm replaces 0.6.2 in src/bootsupport/modules and
src/vfs/_vfscommon.vfs/modules - the collision gate is now live for
make.tcl's guarded require (probed: a bootsupport-only tm path serves
0.7.0 and a collision fixture reports ok=0 status=collision). Layout
copies of src/make.tcl (basic, project-0.1, templates modpod source +
repacked punk::mix templates-0.2.0.tm in bootsupport/vfscommon) carry the
same gate hunks via the modules-step sync channel.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
A source .vfs carrying an actual root main.tcl AND a root fauxlink resolving
to main.tcl (or several such fauxlinks) baked whichever boot script merge
traversal met last - merge_over's fauxlink branch overwrites without warning.
New punkboot::utils::vfs_startup_script_report (0.7.0) censuses root
startup-script suppliers by RESOLVED fauxlink name (empty-nominalname links
included; nested app/main.tcl exempt per G-129). make.tcl consumes it with
the same guarded-require degradation as the G-125/G-133/G-134 checks and
refuses affected kits per-kit under FAILED KITS before any build product is
written - kits from other folders proceed, deployed binaries untouched.
Fixture characterization: startupscript.test (12 tests incl. a
real-source-tree sweep proving today's folders are collision-free);
bootlibrary.test re-run green. Outputs (mint 0.7.0 + bootsupport/vfscommon
promotion) follow in a separate commit.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Increment 3 - the kit-head (opt-in suite step "kithead"):
- build_kithead86/kithead.c: static Mk4tcl+vfs registration, preinit
reading boot.tcl from the exe's own mk4 file, post-init main.tcl pivot
(kbskit kitInit.c reduced to the 8.6 mk4 case; the 8.6.18 headers have
no Tcl_StaticLibrary - stock tclAppInit.c's file-local compat define
mirrored).
- build_kithead86/boot.tcl: kbskit boot.tcl mk4-only/8.6-only (tclInit
override, raw mk::select hand-eval of vfsUtils/vfslib/mk4vfs, mount +
encoding remount, in-kit init.tcl, auto_path reset).
- tools/mk4kit_attach.tcl: setupvfs role under the suite dynamic shell
(mount rw, lib trees + lf-normalized boot.tcl, tclvfs scripts with the
pkgIndex vfs entry rewritten to "load {} vfs").
- build86.zig: kithead exe (core+reg/dde+stubs as tclsh86ts, two-anchor
tclAppInit overlay, engine+binding via build_mk4tcl86 pub lists, static
tclvfs w/ STATIC_BUILD); artifact bin/tclsh8.6.18-mk4-r1.exe; smoke
asserts info library INSIDE the exe. No rechan needed (vfslib memchan
rides 8.6 reflected channels).
Increment 4 - the demonstration (hermetic env, PATH=System32, bare dir):
- head boots with library inside itself on a Tcl-free path;
- the RUNNING head ran sdx and wrapped a SEPARATE COPY of itself
(self-mount rider as specified);
- the starpack runs main.tcl from inside, reads vfs data, loads a
kit-only package, and loads thread2813t.dll FROM the vfs (dll clause
measured, not inherited).
Goal detail: Progress 3+4, Assessment (four candidates vs the four kit
expectations), Decision (mk4 = the 8.6 container and punk86 default;
zipfs backport stays the recorded G-131 second arm), Follow-on-to-parity
list; Status -> achieved 2026-08-02. Archive move follows separately.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Land the ready-to-land fork records in both flows and build the mk4
candidate's loadable shape as a suite battery:
- sources.config: source metakit git (gitea jn/metakit) pinned at
6a92b479 (the G-153-verified tree); matching build.zig.zon .metakit
lazy record (url+hash re-verified live via zig fetch at landing).
- build_mk4tcl86/: new extension module (build_tclvfs86 conventions) -
engine static lib (q4_UNIV set, -fno-exceptions -fno-rtti) + Mk4tcl.dll
(mk4tcl.cpp + bundled mk4too.cpp, USE_TCL_STUBS + BUILD_Mk4tcl) against
the suite stub lib; package version parsed from the staged
Tcl_PkgProvide; installs lib/mk4tcl2.4.9.8/{Mk4tcl.dll,pkgIndex.tcl}.
- build86.zig: build-mk4tcl step + install hook, pkg_smoke gains Mk4tcl,
bootstrapMode source_dirs/recipe_items rows; suite.tcl required-source
+ staged recipe item lists; README deliverable + selection records.
- goal detail: Progress increment record with the verification transcript
facts.
VERIFIED: suite.tcl build -steps {install install-libraries smoke} clones
the fork from the record, builds the dll, and pkg_smoke reports
Mk4tcl:2.4.9.8 in BOTH shells (tclsh86t dynamic AND tclsh86ts static).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::lib 0.6.0: tclparser_tcl stub replaced by delegation to
punk::tclparser; new tclparser_prefer (memoized auto c|tcl dispatch via
namespace-local parse aliases, forcible); tclscript_info and
tclword_to_scriptlist route through it; a+ -using debug puts commented
out (crashed plain tclsh); tclword_to_scriptlist PUNKARGS argdoc added.
New suites: tclparser_engine.test (20 oracle-verified pins + dispatch,
runs everywhere) and tclparser_parity.test (77-case recorded corpus +
range-walk + entry-point parity, capability-gated, oracle dir via
PUNK_TCLPARSER_ORACLE_DIR). 23/23 under tclsh 8.7a6 and 9.0.3; lib
subtree green (8.7 compat.test lpop failure proven pre-existing).
Real 8.6.13 (punksys kit): corpus parity clean; \xHH model corrected -
TIP 388 2-hex cap holds on 8.6 too, version-conditional removed from
the engine. Plain-tclsh fallback demo green both gens (auto_path
cleared): prefer->tcl, tclword_to_scriptlist correct incl nested
array-index command substitutions, output identical to the c path.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New module punk::tclparser 0.1.0 (zero-dependency): parse
command/getstring/countnewline over byte-view scanning (modified utf-8),
same result shapes and error messages as the tclparser C library.
Deliberately does not provide package 'parser' (capability probe).
Parity vs fork oracle dlls: edge corpus 234 comparisons clean per gen;
recursive organic sweep over lib/args/ansi/textblock/tclparser sources =
50005 (Tcl 8.7a6) and 49928 (Tcl 9.0.3) command-parses, 0 fails, all
~330 error-parses per gen message-identical. Generation differences
modelled version-conditionally: \xHH 2-hex cap (8.7+), Tcl 9 bare '('
rejection in array indexes, Tcl 9 nested-brace ${name} scanning.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com