Activation: proposed->active flip (user-confirmed), goals_xref score re-run
recorded in detail Notes (nothing beyond the drafting survey).
Holder named: punk::libunknown zipfs_tm_UnknownHandler's builtin-static
shortcircuit leaked its version-probe child interp 'ptest' whenever an
UNVERSIONED package require of a true static reached the handler -
'package vsatisfies $v' with zero requirement args throws wrong#args,
skipping both interp-delete lines. The leaked non-safe child holds
registrations on the process std channels, so 'chan close stderr' left the
OS handle alive and the slot occupied; the next open got a fileN name and
puts stderr failed (punk91/tclsfe-9.1b0 only: Thread is a true static there,
punk905 loads it from a dll so the block never fires).
Fix (0.2.2): auto-named probe interp deleted in try/finally; zero-requirement
requires accept any provided static version; probe errors fall through to the
normal tm search. Disposition recorded in the goal detail: leak, fixed - not
console-ownership machinery.
Verified: bin/punk91 src script recipe yields channel auto-named stderr with
working puts stderr; libunknown+console+repl suites 105/105 pass (tclsh90).
punkproject 0.22.1 + CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
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
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
Verified nothing depends on the old version or filename before renaming:
all 'package require punk::libunknown' sites are unversioned; punk_main.tcl
and punk::repl locate the module by globbing libunknown-*.tm and picking the
highest by vcompare (so the renamed dev copy now also outversions the stale
bootsupport and project.vfs 0.1 copies deterministically, instead of relying
on tm path order for a same-version tie); bootsupport's
include_modules.config lists it by name only.
The 0.2.0 number retroactively versions the two changes shipped against the
0.1 filename earlier today (register_all_tm deep discovery - a minor API
addition - and the source_pkgindex sourcing-scope fix). A version-history
comment block in the module header now substitutes for the buildversion.txt
changelog other modules carry.
src/modules/AGENTS.md: the punk::libunknown exception bullets now spell out
the manual-versioning mechanics for agents - same Patch/Minor/Major bump
rules as buildversion-tracked modules, executed as a file rename plus Meta
line, manpage_begin, provide-block and version-history updates, with a
check for exact-version/filename dependents before any first bump.
discovery.test/libsearch.test: the source-tree libunknown locator now picks
the highest libunknown-*.tm by vcompare instead of plain lsort (robust to
future version bumps). Verified live in punk902z src: package provide
reports 0.2.0, register_all_tm present, lib.search deep discovery intact.
Suites green under tclsh90 and tclsh87. Build artifacts synced (root
modules/ and _vfscommon.vfs carry only libunknown-0.2.0.tm).
punkshell 0.10.2. Stale 0.1 copies remain in src/bootsupport/modules
(pending 'make.tcl bootsupport') and src/vfs/project.vfs (pending layout
maintenance) - both now cleanly outversioned at runtime.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
zipfs_tclPkgUnknown previously declared 'global dir' and executed pkgIndex.tcl
scripts via 'namespace eval ::' - the pkgIndex $dir contract was met by
writing the global namespace's dir variable, silently overwriting any user
global named 'dir' whenever a package require fell through to the pkg unknown
handler (observed misdirecting a file write into the user's Tcl installation
during test development), and each index's stray unqualified variables (ver,
pkg, script, _CawtSubDirs, ...) leaked into ::.
Index scripts now execute in a source_pkgindex proc frame: $dir is a formal
parameter and auto_path/env are global links - exactly the environment stock
tclPkgUnknown documents (its indexes see dir as the handler's proc-local plus
'global auto_path env'), without stock's incidental exposure of all its other
proc locals. tcl::Pkg::source uplevels into the caller's frame, so the scheme
works unchanged for the 8.6 pre-tip459 fallback. The legacy non-epoch branch
already sourced in the handler frame and simply gains stock parity from the
'global dir' removal.
Reviewed against tcllib 2.0's vendored index behaviours (all compatible):
qualified '$dir ni $::auto_path'/'lappend ::auto_path' extension in the
top-level index, its own apply-scoped subindex sweep (the same isolation
idiom), vsatisfies guards with early return, 'package provide' during index
sourcing (try/pkgIndex.tcl on 9+), and critcl-generated ifneeded strings
(md5c, tcllibc) whose proc definitions run at require time, not source time.
One deliberate divergence from stock: each index file gets its own frame,
so unqualified variables no longer persist between index files within one
sweep (stock shares its handler frame across the sweep) - nothing in tcllib
relies on that.
discovery.test: the GAP pin flips to libunknown_pkgunknown_preserves_global_dir,
plus new pins for the index contract - $dir-based ifneeded/source works,
unqualified 'lappend auto_path' extension reaches the real ::auto_path, and
stray index-script sets don't leak to ::. Verified live in punk902z src:
::dir no longer set at startup, user dir global survives package activity,
tcllib md5/struct::set/json load through the new frame, lib.search deep
discovery unaffected. Remaining startup globals def/pkg/ver come from
punkshell's own boot code (punk_main.tcl foreach loops), not the handler.
punkshell 0.10.1. punk::libunknown remains manually versioned at 0.1;
vfs artifact synced, bootsupport copy untouched as before.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::libunknown gains register_all_tm: walks every tcl:™️:list path
recursively and registers ifneeded scripts for .tm modules at every
namespace depth (the tm unknown handler only registers siblings at the
requested depth, leaving never-requested subfolders like test::* invisible
to 'package names'). First registration wins - parity with the handler and
the shadowing pins. Reuses/populates the per-epoch directory index cache
(zipfs whole-tree listing; per-dir globs for filesystem paths; #modpod-*,
#tarjar-* and _build skipped) and runs at most once per tm epoch per
interp - the guard is the interp-local tm_fullscan variable, deliberately
not in the shareable epoch dict since ifneeded registrations are
interp-local.
punk::mix::commandset::loadedlib 0.2.0: search runs register_all_tm plus
the auto_path pkgIndex sweep by default when punk::libunknown is active,
so 'dev lib.search test' now shows deep modules without -refresh.
-refresh is repurposed to mean a genuine filesystem re-scan: package epoch
incr (invalidating the scan caches) then rediscovery - picking up .tm
files added/removed on disk. Without punk::libunknown (or with an older
copy lacking register_all_tm) -refresh falls back to the previous
dummy-require deep walk. Dependency fixes: highlight ansi computed only
when -highlight 1 via qualified punk::ansi with inline require (previously
relied on the shell-global a+ alias unconditionally and errored in bare
interps), inline requires for punk::path (fallback walk) and textblock
(table output).
New test suites (green under tclsh90 and tclsh87):
- modules/punk/libunknown/testsuites/discovery/discovery.test: lazy-depth
sibling registration, register_all_tm all-depths/cached-per-epoch/
head-wins-parity, package epoch shape and trace-driven increments,
epoch-cache short-circuit + incr recipe, and a GAP pin of
zipfs_tclPkgUnknown clobbering a user global 'dir' variable (stock
tclPkgUnknown keeps dir proc-local; fix candidate).
- modules/punk/mix/testsuites/loadedlib/libsearch.test: search match
semantics, default deep discovery, -refresh re-scan contract, highlight
without shell-global ansi aliases.
Both suites source the source-tree punk::libunknown directly by path:
'package require' would tie-break the same-version bootsupport copy by tm
path order (testinterp order favours bootsupport; child-interp
'tm::add {*}list' reverses precedence).
Verified live in 'punk902z src'. Build artifacts synced via make.tcl
packages + vfscommonupdate (loadedlib-0.2.0.tm, libunknown-0.1.tm).
Note: src/bootsupport copy of punk::libunknown intentionally untouched -
becomes stale until the next 'make.tcl bootsupport' sync; loadedlib
degrades gracefully against it. punk::libunknown remains manually
versioned at 0.1.
punkshell 0.10.0 (see CHANGELOG.md; also records the 0.9.1 doc-only
-refresh help rewrite).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com