Refresh via make.tcl modules + vfscommonupdate after the argparsingtest
1.0.0 restructure: _vfscommon.vfs swaps argparsingtest-0.2.0.tm for the
version-stamped 1.0.0 build. argparsingtest is not in the bootsupport
include_modules.config, so no bootsupport snapshot is affected (the
stale src/bootsupport/modules/argparsingtest-0.1.0.tm remains a known
prune leftover). Kit builds (make.tcl project) not run this change-set.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Restructure of the parser-timing module around three calling styles:
- parser procs move into per-style child namespaces argparsingtest::opts /
::tkstyle (2 leading positionals) / ::tclstyle (2 trailing positionals),
with identical short proc names across styles; the test1_ prefix is gone
- hand-rolled parsers share a manual_ prefix (manual_ni, manual_switch,
manual_prefix, ...) so they group visually in the comparison tables;
test1_prefix2 removed (not meaningfully distinct from test1_prefix)
- tkstyle/tclstyle carry a representative roster (manual_switch baseline +
punkargs/punkargs_by_id/punkargs_parsecache + opt + cmdline + tepam);
style parsers return a {p1 p2 opts} list
- new 'unsupported' discovery status for library/style combos the backing
library cannot express: cmdline with leading positionals (getoptions stops
at the first non-option word - probe verified), argp with any positionals
(parseArgs walks the whole list as option pairs - source verified).
compare renders these as N/A rows below the timed rows so every library
still appears in every style's table
- harness procs (discover_parsers/timeit/first_call/compare) gain
-style all|opts|tkstyle|tclstyle and return results keyed by style;
-args requires a single -style (each style has its own default vector);
external probe keys drop the test1_ prefix (getopt/parse_args/argparse/cmdr)
- punkargs_by_id variants keep the eager punk::args::define as sole doc
source (the former duplicate argdoc lappend made the lazy namespace scan
undefine/re-register the id on first introspection); unused struct::set
require dropped; opt/cmdline/tepam requires hoisted to module top;
first_call library warm-ups extended with positional coverage
- test suite rewritten: 17 tests including per-parser {p1 p2 opts} contract
checks across both positional styles, N/A table rendering, roster counts
and the -style/-args error paths
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New goal (user-approved wording): make.tcl bakes a curated scriptlib into
kit vfs app/scriptlib so standalone binaries have working lib: scripts, with
precedence following the packagemode mental model - kit-internal-wins only
for the default 'internal' launch, src/dev modes putting the live project
scriptlib first, and proj: (G-033) adding the visited project's scriptlib.
Context records the 2026-07-18 findings: kit-internal resolver branch never
exercised (no build path exists), not-overridable policy scoped to default
mode per user direction, missing boot->runtime packagemode hint, cookfs
mount-root gap, and the out-of-scope app-shellspy mapping. goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Batch refresh via make.tcl packages/bootsupport/vfscommonupdate: punk::path
0.2.2 -> 0.3.0 (extensionless lib: tcl identification - this change-set),
plus promotion of punk::args 0.12.6 and punk::ns 0.9.0 built at the previous
source commit. vfscommon lib copies of app-punkscript/app-punkshell/
app_shellrun pick up the shared scriptlib_resolve refactor. Includes the
project-layout bootsupport snapshot copies (punkboot-bootsupport installer).
Kit deploys to bin/ for punk91.exe and punk902z.exe were blocked by running
shell instances holding the executables (build reported the failed deletes);
rerun make.tcl project (or close the shells first) to deploy - tests were
run against the freshly built kit from src/_build.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
scriptlib_resolve now lets an extensionless (or unknown-extension) lib:<name>
call match a file named exactly <name> when its first lines identify it as
tcl: a leading '# tcl' comment (prefix, case-insensitive), a shebang naming
tclsh/tclkit/wish, or the portable sh-trampoline ('#!/bin/sh' with a
commented 'exec tclsh' continuation - detected within the first 4 lines).
New internal punk::path::system::scriptfile_is_tcl does the bounded sniff
(512 bytes, UTF-8 BOM and CRLF tolerated, directories/unreadable files
rejected). When both <name> and <name>.tcl exist, the spelling matching the
call wins, checked per scriptlib location so kit-internal directory
precedence is never crossed by a spelling preference.
.kit joins the known extensions: lib:<name>.kit previously had .tcl appended
(searched <name>.kit.tcl), which made the shell subcommand's do_tclkit
dispatch arms unreachable - lib: kit dispatch is now restored. Result dict
reworked: scripttype (tcl/kit/py/pl/ps1/sh or empty) + notes keys added,
scriptname is now the matched relative name, and matches require file isfile.
app-punkshell and app_shellrun lib: handling refactored onto the shared
resolver (previously independent inline copies of the policy), fixing two
silent-failure bugs in that copy: no message at all when a scriptlib dir
existed but lacked the script, and the error listing showing
<kit>/scriptlib rather than the <kit>/app/scriptlib actually checked.
app-punkscript's post-resolve gate now uses scripttype and its not-found
report includes the identification skip notes. The unused has_globchars
vestige is dropped.
Fixtures scriptlib/_punktest/{extless,dual,dual.tcl,shebang_sh,notatcl} and
5 new scriptexec.test cases (extensionless resolve, both precedence
directions, trampoline shebang + argv, non-tcl skip note on not-found);
suite passes 17/17 against a freshly built punk902z kit. Sniff helper unit
checks pass under tclsh 9.0.3 and 8.6. punkshell project 0.13.0 -> 0.14.0.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::ns 0.9.0: cmdhelp (i) gains -return text - plain-text argument
documentation for machine/LLM consumption: no ANSI, no table layout, the
argument section of every command form rendered in one output under a common
header ('i -return text after' shows all six forms), G-041 form selection
still honoured when argument words are supplied, no advisory-parse error
preamble (-return dict remains the parse-status surface). Implementation
delegates resolution to the -return dict recursion and renders per-form via
the string renderer.
punk::args 0.12.6 (user direction; string-form layout explicitly not frozen -
no external consumers yet):
- arg_error renders the error message + per-form match detail exactly once,
BELOW the usage display (was above and below); bottom append suppressed for
empty messages.
- string renderer argument rows are single-line
'name TYPE:type(constraints) ?DEFAULT:'val'? ?MULTI:yes?' - type
constraints parenthesize onto the base type instead of line-breaking
mid-row; empty DEFAULT/MULTI labels and whitespace-only help blocks omitted.
- choices render as markdown-subset bullets '- `choice` - label' with label
continuations at a fixed deeper indent - choice names are now
machine-distinguishable from label text without ANSI. Structural contract:
column-0 lines bearing TYPE: are argument rows, indented lines are
documentation, backticked bullets are choices. Table cells unchanged.
New scriptlib/developer/whatis.tcl (runtime command introspection for
agents): resolved name, subcommand-chain resolution via punk::ns::cmdinfo
('whatis string is'), kind, providing package + loaded version, origin file,
proc definition file:line, punk::args synopsis; -body appends the runtime
body with file-relative line numbers, -doc the full plain-text argdoc via
cmdhelp -return text (with fallback for older punk::ns). Backing the
cross-framework tcl-whatis agent skill: canonical .agents/skills/tcl-whatis/
(Agent Skills standard - pi/OpenCode/Codex) with byte-identical copy in
.claude/skills/ for Claude Code; .gitignore gains !.claude/skills/ with the
fossil ignore-glob comment + exception-set docs updated per the dual-VCS
contract (fossil adds staged). Root AGENTS.md: .agents/skills index entry,
whatis pointer in Repo-wide Notes, scriptlib/developer example.
Tests: new pins cmdhelp_return_text_all_forms/_argword_form_selection/
_single_form_plain_marker (cmdhelp.test), rendering_stringmode_singleline_argrows
+ rendering_stringmode_choice_bullets (rendering.test); deliberate-change pin
updates: errorselection.test message matches gained leading * and cmdhelp.test
message pins sample the last line (message placement). Full source-tree suite
963/979 pass, sole failure the pre-existing exec-14.3 baseline; make.tcl
modules clean.
Project version 0.12.42 -> 0.13.0 with CHANGELOG.md entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules/bootsupport(x2, 2nd pass copied 0)/vfscommonupdate/project
sequence per the workflow overview. Kit vfs payload and bootsupport module
sets (incl project_layouts bootsupport copies) updated to the new built
versions; superseded 0.12.4/0.8.0/0.1.0 copies removed.
Kits: punkbi.exe and punksys.exe rebuilt and deployed (punksys verified
carrying 0.12.5/0.8.1/0.2.0); punk91.exe and punk902z.exe deployment skipped -
target binaries in use by running shells - redeploy after closing them.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Goal for embedding a short marker in the usage/error table's bottom frame edge
(bottom-right @examples indicator, counterpart of the top 'Usage' title). Two
severable deliverables: frame-parity -subtitle/-subtitlealign on
textblock::class::table (must work with or without footer rows), and footer
rows with column spans independent of the body via configure_footer mirroring
the header API (the -show_footer/-ansibase_footer/-ansiborder_footer styling
knobs already exist but no footer-row methods do). arg_error's interim
'Example:' header row retires when this lands.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
parse -cache overhaul:
- VALIDATION trap's parse_cache write now explicitly gated on -cache (formerly
unconditional but landing in a discarded proc-local for -cache 0 by scoping
accident - 'variable parse_cache' only ran on the -cache 1 branch)
- cached validation errors stored as per {errorstyle callertext} render
variants under a {arglist definition form} main key (-caller dropped from the
main key - results don't depend on it); a missing variant falls through to a
fresh render. Previously the first caller's errorstyle and %caller%
attribution were baked in and replayed verbatim to later callers.
- @dynamic definitions (and legacy leading '-dynamic 1') are never cached so
re-evaluated substitutions always take effect; dev/dynamic-cache.test
known-bug pin flipped
- new punk::args::parse_cache view/clear proc (sgr_cache style); guarded
variable init; -errorstyle definition default corrected to the operative
'standard'. New parsecache.test (7 tests).
synopsis notation + internal @form -synopsis retirement:
- ::punk::args::parse/::parse_status dropped their stale @form -synopsis
overrides (omitted -cache/-caller) for auto-generated lines shaped with
-typesynopsis {<int|formname>...} on -form; drift pin
synopsis_parse_generated added
- punk::ns::synopsis no longer errors on custom @form -synopsis lines that are
not valid Tcl lists (e.g Tcl manpage style '?-form {int|<formname>...}?' -
's parse' raised 'list element in braces followed by ...'): non-list lines
take a textual command-head replacement fallback
- @form -synopsis directive help rewritten (display-only, any style, prefer
auto-generation, known warranted case: script-level/constructed ids);
::punk::args::synopsis -help gains a notation legend and a new @examples
block comparing Tcl man-page ?...? style with the bracket style (punk::args::eg)
eg usability + examples indication:
- punk::args::eg resolves relative/unqualified command names (punk::ns::cmdinfo
from calling context when loaded, else global qualification) - in namespaces
where it shadows the global 'eg' alias (e.g ::punk::args) 'eg list' returned
empty while 'i list' worked; unknown ids now return a message naming the id;
punk::ns::eg hands the typed name through on unresolved docids
- usage-table 'Example: eg <id>' header row now uses scheme colour CLR(check)
(interim display until G-088 footer/subtitle support)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New procs timeit/compare/discover_parsers/first_call for rough cross-parser
performance comparison (punk::args variants vs hand-rolled dict/switch/prefix,
tcllib opt/cmdline/tepam, argp), with PUNKARGS argdoc coverage throughout.
first_call times each parser twice in fresh child interps:
- cold: first call after package load (includes byte-compilation of the parser
proc body and any backing-library procs it invokes)
- warm: the backing library is pre-exercised via per-library sacrificial
warm-up scripts (library_warmups dict) so the timed call isolates per-proc
first-use cost. Replaces an earlier punk::args-only
'punk::args::parse {} withdef {}' warm hack that was unfair to the other
libraries under test and only partially warmed punk::args itself.
Child interps pin package requires to the parent's loaded versions
(punk::args, punk::lib when present, argparsingtest) - plain package require
prefers stable versions, so children otherwise timed older stable copies
visible on the module paths instead of the dev module under test; under
Tcl 8.6 the punk::lib pin also supplies the lpop compat shim punk::args::parse
needs, unbreaking punk::args timing in bare child interps there.
compare renders first_cold/first_warm columns (table), nested cold/warm
sub-dicts (dict/json). New test suite under src/tests/modules/argparsingtest.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Prints the release-ready command sequence, source -> built-packages ->
bootsupport / kit-vfs / kit-executable folder-flow diagrams, and keyed notes
(magic-version stamping, punkcheck provenance, staleness gate, -confirm
policy, locked-exe deploys, VCS-tracked output targets). The text is embedded
in make.tcl (::punkboot::workflow_text) rather than a data file so it travels
with the make.tcl copies seeded into generated-project layouts; content is
project-generic accordingly. A MAINTENANCE key in the output states the
update contract.
punk::args-documented via the existing constructed-definition machinery
(SUMMARIES/HELPTEXTS/SUBOPTS + informational SUBGROUPS entry) so tabled help,
'help workflow' and the top-level subcommand table all cover it; also
registered in known_commands and the plain punkboot_gethelp fallback, and
exempted from the bootsupport staleness gate alongside check/projectversion.
Verified in normal and PUNKBOOT_PLAIN dispatch; stray arguments raise a
punk::args toomanyarguments usage error; output is pure ASCII, width <= 100.
src/AGENTS.md Work Guidance gains the agent update contract: change the
workflow text in the same change-set as any build data-flow change, keep the
ASCII/width/structure rules, verify with 'make.tcl workflow' (+ one
PUNKBOOT_PLAIN run), and the registration-point checklist for subcommand
changes. Layout make.tcl copies propagate via 'make.tcl bootsupport' - never
hand-synced. punkshell 0.12.42.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl vfscommonupdate -confirm 0 after the 0.12.4 modules build. Besides
punk::args 0.12.3 -> 0.12.4 (collision-aware resolve miss path), the REPLACE
pass brought _vfscommon.vfs up to date with built modules that had not been
propagated since the 0.12.37 refresh: cap handlers templates 0.2.0, mix
base 0.1.1, mix commandsets layout/module/scriptwrap 0.1.1 + project 0.2.2,
mix templates 0.1.5, fauxlink 0.1.2/0.2.0, tomlish 1.1.12 + test module
catch-up (test/tomlish-1.1.5 content matches built copy).
make.tcl project -confirm 0 rebuilt the kits: punkbi.exe and punksys.exe
deployed to bin/; punk91.exe and punk902z.exe builds succeeded but
deployment to bin/ was blocked by running shell instances holding the
binaries (fresh kits left in src/_build - redeploy after closing shells).
Kit executables are not tracked; this checkin is the vfs source tree only.
argparsingtest work (module 0.2.0, tests) deliberately left uncommitted;
its derived vfs artifacts (argparsingtest-0.1.0.tm removal / 0.2.0.tm
addition) are likewise excluded from this checkin.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
resolve's first-sighting path for a rawdef whose @id is already registered
with different content now purges the id's existing cache entries (quiet
undefine) before registering, mirroring define's re-creation behaviour.
Previously it repointed id_cache_rawdef while stale rawdef_cache_about /
rawdef_cache_argdata entries lingered - two rawdefs claimed the same id and
a subsequent define with the original text was a silent no-op (stale
cache-about hit), leaving withid lookups stuck on the inline definition.
The disabled blanket "called with undefined id" stderr warning is removed -
it flagged supported inline usage (parse ... withdef, direct resolve
calls). Guard checks id_cache_rawdef directly (id_exists also matches
aliases, where the rawdef lookup would error). Known residual: the miss
path still records no -defspace for @dynamic definitions first seen via
resolve.
New define.test pin define_resolve_id_shadow (characterized pre-fix: the
re-define no-op reproduced with the purge disabled). punk::args suite green
under Tcl 9.0.3 (228 passed, 0 failed). punkshell 0.12.41.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The layout custom/_project bootsupport sync picks up files newly arrived in
src/bootsupport on the following run (same two-pass propagation as the guarded
prune tooling); punk.project-0.1 and punk.shell-0.1 copies now carry the
stage-2 handler/modpod versions with the superseded copies pruned.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport refresh following the stage-2 cutover; superseded 0.1.1
handler and 0.1.4 modpod pruned (the modpod copy required manual deletion -
the running make.tcl mounts it and the prune self-locks; flagged in the G-087
detail file). Layout custom/_project bootsupport copies mirrored by the build.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::cap::handlers::templates 0.2.0: layout refs are fauxlink files
(<alias>#<encodedtarget>.fauxlink|.fxlnk, target relative to
<projectroot>/src/project_layouts, resolved via the fauxlink module).
get_itemdict_projectlayoutrefs selects *#*.fauxlink/.fxlnk with fauxlink-derived
names; get_itemdict_projectlayouts derives the layout folder from the resolved
targetpath; the <alias>@<target>.ref parser is removed and .ref files are no
longer recognised. Alias-less (leading-#) refs and unresolvable refs are
skipped with a warning - punkcheck-based tooling excludes leading-# filenames,
so layout refs must carry a non-empty nominal name. Also fixes the ignore*
skip, which previously matched against the full glob path and never applied.
All 7 live-tier refs renamed via a fauxlink::link_as-driven migration script
(each generated name round-trip-verified through fauxlink::resolve before
rename): decktemplates vendor/punk x4 (alias-less refs gained their target-tail
aliases: basic, minimal, sample-0.1), custom/_project x2, and the
module-shipped modpod ref (punk::mix::templates 0.1.5). Zero-byte property and
all visible layout names unchanged. src/project_layouts/README.md ref-grammar
section rewritten for fauxlink.
Note: git's rename pairing crosses two of the zero-byte vendor/punk refs
(sample-0.1 <-> project) - content-identical empty files; the true mapping is
alias-preserving as described above.
Verified: stage-2 scratch checks 7/7 (name parity incl exact punk.project,
decoy alias-less ref warned+skipped, old-grammar decoy ignored); runtests
prune/fossilmove/multishell/libsearch pass; end-to-end dev project.new
materializes a full project from the default punk.project layout.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport: fauxlink 0.1.2 -> 0.2.0 in src/bootsupport and the
custom/_project layout copies; superseded 0.1.2 pruned, along with the layout
copies' templates-0.1.3.tm prunes deferred by the earlier transient lock.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- CHANGELOG + version bump for the fauxlink 0.1.2 vendor pull, tomlish catch-up
and bootsupport refresh.
- G-087 detail Notes updated: fauxlink 0.1.2 upstream work record, punkshell
fauxlink consumer survey (fcat follows only .fauxlink not .fxlnk; make.tcl
merge_over + startup-script check; kit boot fallback), the (package) id
status relative to G-075, and the recorded intention that punk::nav::fs
should gain fauxlink handling analogous to its punk::winlnk shortcut
treatment (candidate goal).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport batched build-output refresh (punkcheck-managed): fauxlink
0.1.1 -> 0.1.2, plus catch-up of source versions that had moved since the last
refresh - punk::ansi 0.1.3, punk::args 0.12.3, punk::lib 0.5.0, punk::ns 0.8.0,
punk::repl 0.5.2, tomlish 1.1.10 -> 1.1.12, test/tomlish-1.1.5 modpod, and this
morning's G-087 hygiene bumps (cap handlers templates 0.1.1, punk::mix::base
0.1.1, commandset layout/module/scriptwrap 0.1.1, commandset project 0.2.2,
punk::mix templates 0.1.4). Superseded versions pruned; the same refresh is
mirrored into the custom/_project layout bootsupport copies by the build.
templates-0.1.3.tm prune initially failed with a transient file lock and was
removed manually after verification.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Pulled by the same vendorupdate run from the clean tomlish upstream checkout
(c:/repo/jn/tclmodules/tomlish): tomlish 1.1.12 added alongside earlier
versions per existing practice; test/tomlish-1.1.5.tm modpod refreshed in
place from its source.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Vendored from the now-committed upstream project (c:/repo/jn/tclmodules/fauxlink,
checkins c82c9bb9 + ed1eebdb): punk::args documentation blocks including a
(package)fauxlink id (inert PUNKARGS + registration, no punk::args dependency;
full surfacing awaits G-075), decode_unicode_escapes hexless-%U first-char-drop
fix, 3-segment comment validation/decoding parity, link_as stub now errors
instead of silently no-oping, and a 62-test upstream suite (src/tests/fauxlink.test)
covering resolve/decode behaviour and the documentation metadata.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Two independent list-flattening bugs made `runtests.tcl foo.test bar.test`
match zero files, forcing agents to run files individually:
- the trailing glob value is -multiple 1, so its parsed value is a list;
plain lappend nested it as a single space-containing element
- punk::path::treefilenames declares tailglobs as a -multiple 1 positional
(one glob per argument), but the whole file_globs list was passed as one
argument, re-collapsing it (this also broke multiple globs supplied via
-tcltestoptions {-file {...}})
Single names always worked because a one-element Tcl list flattens to
itself, which masked both bugs. Verified: two file tails now discover and
run both suites (files=2, 40/40 pass).
Also note multi-file-tail support in src/tests/AGENTS.md Work Guidance.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- punk::mix::templates modpod (0.1.4): dead templates/layouts/project payload
subtree removed - design-generation residue with no reader; layout payloads
live in src/project_layouts, located via layout_refs.
- src/make.tcl: unused old_layout_update_list (referencing the long-gone
src/mixtemplates and modules/punk/mix/templates paths) removed; bootsupport
help text now names src/project_layouts/custom/_project/<layoutname> instead
of mixtemplates.
- src/project_layouts custom/_project make.tcl copies: punkcheck-managed sync
outputs refreshed by the verification 'make.tcl modules' run.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- @vendor+punk+project-0.1.ref renamed to project@vendor+punk+project-0.1.ref:
the alias yields the exact layout name 'punk.project', so project.new's
defaulted -layout resolves unambiguously (previously tcl::prefix::match saw
only punk.project-0.1 / punk.project-0.1_overrides).
- Junk/test refs removed from the selectable layout list: test2, the
custom/_project duplicate sample-0.1 ref, and the alias-less punk.shell-0.1
ref whose target was an a.txt-only folder (folder removed too; the real
shell layout remains exposed as punk.shell-0.1_overrides).
- src/project_layouts/README.md rewritten to describe the implemented
punk.templates + layout_refs mechanism including the ref filename grammar,
the not-yet-implemented overlay semantics, and a G-087 pointer; the dead
punk.projectlayout capability description is gone.
Layout names after this change: punk.sample-0.1 punk.project punk.minimal
punk.basic punk.shell-0.1_overrides punk.project-0.1_overrides.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- put -> puts at all six no-handler warning sites (commandset layout x2,
project, module, scriptwrap, mix/base get_template_basefolders - the sweep
found three sites beyond the review's list). Three procs also dereferenced
an unset result variable after the warning; the no-handler paths now warn
and return an empty dict. layout references_as_dict and module templates_dict
warning messages no longer misattribute their owning proc.
- punk::cap::handlers::templates: brace the absolute-pathtype existence test
('if {!file exists $normpath}' raised an expr syntax error on any
absolute-pathtype provider registration), and add the missing dict-exists
check in pkg_register's duplicate-registration guard (errored 'key not known
in dictionary' for any second provider package registering a capability).
- Versions: commandset layout 0.1.1, project 0.2.2, module 0.1.1,
scriptwrap 0.1.1, cap handlers templates 0.1.1; punk::mix::base 0.1 -> 0.1.1
(manually versioned: file renamed, provide block updated, history comment
added).
Verified: scratch no-handler/registration checks 13/13 (see
goals/G-087-thin-project-layouts.md Progress); runtests prune/fossilmove/
multishell/libsearch all pass; make.tcl modules builds clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New goal from the 2026-07-16 layout-system review: thin layouts with
generation-time infrastructure injection, fauxlink layout refs, and a working
overlay merge primitive. Detail file carries the review findings (unimplemented
merge, dead module-pathtype refs, stale fat snapshots, latent bugs), the staged
approach (hygiene first), and the hygiene-stage completion record.
Activated at user direction 2026-07-17.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Vendored library payloads and vfs kit payloads legitimately carry CRLF
endings (upstream files are kept as-is; the LF preference governs authored
text). Without the globs, large vendor/vfs checkins block on fossil''s
interactive CRLF prompt - the tablelist 7.11 catch-up (fossil 3316d3c7)
had to use --no-warnings. Policy documented in .fossil-settings/AGENTS.md
alongside the binary-glob rationale. crlf-glob is fossil-only (no
.gitignore-style counterpart), so no dual-VCS derivation applies.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The old Tk dll set aside during the punk9win.vfs split is no longer
wanted in the tk903 kit payload; the 9.0b2-era dll remains available in
punk9wintk90b2.vfs.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Closes the loophole flagged in the 6.22 -> 7.11 swap: with the .tm
files deleted, a future make.tcl vendorupdate would have regenerated
them from these entries. tablelist now ships solely as the
src/vendorlib/tablelist7.11 pkgIndex lib.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The punk9win.vfs kit was split into punk9wintk90b2.vfs and
punk9wintk903.vfs; the treectrl/Img/twapi/cffi payloads G-020 relies on
live in punk9wintk903.vfs/lib_tcl9 (the actively mapped tclsfe/punk91
kit). Path-only update, user-approved; goal contract otherwise
unchanged. goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New vfs_startup_script_warning check runs for each .vfs folder about to
be built against a runtime: it passes if the folder has a root main.tcl
or a root fauxlink resolving to the name main.tcl whose target exists
and is a .tcl file. Otherwise a noticeable warning is emitted and the
build proceeds (a kit with no startup script is legal).
Warnings use a new general-purpose ::punkboot::print_build_warnings
channel: column-0 BUILD-WARNING: token for greppability, ANSI highlight
for humans, and recap at end of run via the wrapped ::exit (same
treatment as PROVENANCE-WARNING). Overlay-only folders with no runtime
mapping (e.g _vfscommon.vfs) are not checked. Contract documented in
src/vfs/AGENTS.md.
Motivated by the punk9win.vfs split initially dropping the main.tcl
punk_main fauxlink from punk9wintk90b2.vfs.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Adds the main.tcl fauxlink omitted from the punk9win.vfs split, and
points the commented-out tclsh90b2/tksfe-twapi-x64 mapvfs.config
entries at the new kit names.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Remove src/vendormodules/tablelist-6.22.tm and tablelist_tile-6.22.tm
in favour of the multi-file src/vendorlib/tablelist7.11/ (pure Tcl,
upstream layout with pkgIndex.tcl). _vfscommon.vfs follows via
make.tcl vfscommonupdate: modules/tablelist*-6.22.tm removed,
lib/tablelist7.11 added.
Note: src/vendormodules/include_modules.config still lists the
tablelist/tablelist_tile module sources; a future make.tcl
vendorupdate would regenerate the 6.22-era .tm files unless those
entries are removed.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Replace the single punk9win.vfs payload with two per-Tk-version kits:
- punk9wintk90b2.vfs: content-identical copy of punk9win.vfs (same Tk
9.0b2-era bin/tcl9tk90.dll) except the main.tcl punk_main fauxlink
was not carried over (kit is parked; its tclsh90b4_piperepl mapping
remains commented out in mapvfs.config)
- punk9wintk903.vfs: same payload with a newer Tk bin/tcl9tk90.dll
(Dec 2025 build, Tk 9.0.3) and the old 9.0b2-era dll set aside as
bin/tcl9tk90xxx.dll; adds lib_tcl9/apave4.4.10 (pure Tcl); drops the
modules_tcl9 Thread-3.0b3 modules (Thread is static in the tclsfe
runtime); now the mapping target for tclsfe-x64.exe (punk91 kit)
src/runtime/mapvfs.config and src/runtime/vendorlib_vfs.toml (tcludp
install targets) retargeted from punk9win.vfs to the new kit names.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-directed removal of the two pipeline-based development iterations flagged
as candidates in the 0.7.0 hygiene pass. Both were undocumented, unexported
global aliases superseded by the plain proc nscommands (which adds
weird-namespace handling); no callers existed in the repo and nscommands1 was
broken - it referenced nonexistent commands (nsthis2, inspect at global
scope) and errored on first use. Recoverable via git history.
ns/nav/repl suites 111/111 green. buildversion 0.7.1 -> 0.8.0 (command
removal); project 0.12.36 + CHANGELOG (patch - the aliases were never part of
the documented shell contract).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved from the serversecretsync tm-path-shadowing incident
(8.6 require-before-path-setup silently selected a stale tomlish from the
machine-default tm paths over the project's vendored copy). Default
mechanism per user: vendor punk::libunknown + punk::packagepreference as
the light layout's bootstrap minimum. Related: G-012/G-027/G-029/G-035.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The -return summarydict choicelabel claimed the linemap key appears only when
-n is supplied - actual behaviour (pinned in ansi/grepstr.test since the
characterization wave) is that linemap is always present. Help text corrected
to match; deferred-to-the-hygiene-pass item from the grepstr characterization.
ansi suites 63/63 green. buildversion 0.1.2 -> 0.1.3; project 0.12.35 +
CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Both fixes were pinned as known warts before the change; the pins flip with it:
- get_nslist: the -types default sat inside a braced dict-create literal, so it
was the literal string $known_types - any call without -types (notably bare
user-level `nslist`) errored with the malformed "Unrecognised namespace
member type: $known_types". An unsupplied -types now defaults to all known
member types. Pin flipped: nslist.test nslist_types_default_error_QUIRK ->
nslist_types_default (bare nslist renders children + commands). nslist's own
PUNKARGS -types gained help text, deliberately without a -default so the
passthrough stays absent when unsupplied.
- nsjoinall: the non-empty-prefix-vs-absolute-path error message carried a
copy-paste "nsjoin:" prefix - now "nsjoinall:". Pin flipped in
nsprimitives.test nsjoinall_edges.
- nscommands: commented out a development trace puts (">>> base: ...") that
polluted stdout on the weird-namespace path (same treatment as the 0.1.1
doc-lookup trace-puts cleanup; not pinned).
Suites green: ns/nav/repl 111/111; full source-tree run at the known baseline
(only core exec-14.3, pre-existing). buildversion 0.7.0 -> 0.7.1; project
0.12.34 + CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
No change to shipped behaviour (ns+nav+repl suites 111/111 green). Minor bump
because unused procs were removed.
Removed (~1200 lines, recoverable via git history):
- the fully commented-out predecessor help command arginfo (~930 lines) -
its own header marked it replaced by cmdhelp
- superseded/deprecated name-primitive twins nsparts1, nsprefix1,
nsprefix_orig, nstail1, nstail_orig (never exported, no callers; NOT
drop-in equivalents - divergence on 5+ colon runs was pinned in
nsprimitives.test before removal; those divergence pins are removed with
the twins and replaced by a direct nsprefix long-colon-run pin - the
divergence record lives in the test file history, commit 0c7168a1)
- obsolete nsglob_as_re1, empty stubs ns_relative_to_location/
ns_absolute_to_location, obsolete internal::_pkguse_vars, an if-0 block in
nstree_list, unused interp_aliases assignment in get_ns_dicts, assorted
commented-out remnants (pre-punk::args defaults blocks, pipedata width
calcs, corp default-retrieval experiments, cmdtrace trace-add alternates)
Documentation accuracy:
- nsprefix comment corrected (:::a prefix is :: not ::a - per pins)
- nsglob_as_re stale "should be fixed" note replaced with an accurate
description of the in-place negative-lookahead fix (* matches an inner
single colon, never crosses ::)
- nstree_list previously empty PUNKARGS summary/help fields filled
- nstail gained a doc comment; nseval_ifexists gained the native-vs-punk
p:::x divergence note; the dangling "string functions" sentence completed
- cmdhelp help typos (auto-gnerated, commands commands); corp -syntax help
truncated sentence completed
Flagged, deliberately unchanged (comment only):
- get_nslist red-strike/masked alias display branches appear unreachable
from current bucket derivation (nslist.test fixture findings) - reassess
at the planned display rework
- nscommands1/nscommands2 pipeline aliases: superseded removal candidates
(nscommands1 errors on first use - references nonexistent nsthis2)
- cmdtrace stdout/stderr noise deferred to proposed G-085
- test_switch* marked as live cmdtrace test fixtures (used by cmdtrace.test)
All inserted/updated comments carry 2026-07-14 Agent-Generated/Agent-Updated
marks. buildversion 0.6.0 -> 0.7.0. Known-wart fixes sanctioned by the pinned
backlog (nslist -types default, nsjoinall error prefix) follow separately.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New shell/testsuites/punkexe/shellnavns.test - one hang-proof punk_run piped
session against the built executable in src launch mode (dev modules, so
current punk::repl/nav source is exercised without a rebuild):
PROVEN end-to-end:
- n/ sets ::punk::nav::ns::ns_current in the running shell
- the current namespace continues into `subshell punk` and back out, and the
0.5.2 stray-namespace seeding fix holds live (no phantom ns_current
namespace in the subshell context)
- navigation inside the subshell takes effect; the session exits cleanly
(exitcode 0, no timeout, exit unwinds subshell -> parent -> terminate)
FINDINGS from the E3 probes (pinned in the test with markers):
- the FIRST subshell evaluates in the SAME code interp as the parent shell -
the "first subshell asymmetry" already TODO-documented in repl::init.
Continuity therefore manifests via shared state at shell level (SHARED
marker: a variable set in the subshell is visible to the parent after
exit, and the parent adopts the subshell''s final namespace). The
repl::start seeding template - the carry-over mechanism for genuinely
separate code interps - is proven at module level in punk/repl
nscurrent.test. A G-002-style isolated subshell would flip these pins.
- KNOWN GAP: piped-session submissions evaluate at :: even after n/ sets
ns_current - the inscope application proven interactively and at module
level does not take effect for subsequent piped submissions in this spawn
shape. Root cause undetermined (piped-path evaluation vs kit/codethread
interplay); flagged for investigation alongside G-038 session-context
work.
Verified: shell/** suite 42 total / 40 passed / 0 failed (2 gated skips)
under Tcl 9.0.3. AGENTS updated (shell contracts bullet; punk/repl module
index E3 reference).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Groundwork requested for the future rework of n/ n// n/// output to punk
tables with terminal-width responsiveness: the underlying display elements
and navigation/retention semantics are now pinned so only deliberately
REWORK-flagged pins flip when the layout changes.
- punk/ns nslist.test (11): tier A pins get_ns_dicts classification buckets
(the machine contract: children/packagetails/packageprefixes per the
package-names derivation, commands/exported/imported/aliases/procs/
ensembles/oo/coroutines/usageinfo incl alias-target doc resolution and its
update_definitions dependence, alias edge cases, native via builtin ns);
tier B pins per-element marking layout-agnostically (underline/underdouble/
underdotted package styles, type tag colours, exported green / imported -I
under overtype SGR canonicalization, the punkargs doc icon); tier C pins
the CURRENT hardcoded 2-col/4-col layout and nspath subtables, explicitly
flagged to flip with the rework; KNOWN QUIRK pinned: bare nslist without
-types errors with a malformed message (literal dollar-known_types).
Findings recorded: the red-strike/masked alias display branches appear
unreachable from current bucket derivation.
- punk/nav/ns navns.test (6, new suite dir): ns/ navigation state machine
(absolute/relative/glob-no-nav/failed-nav preservation/quad-colon
normalization), v-form content selection, ensemble annotation, and the
::punk::nav::ns::ns_current variable contract.
- punk/repl nscurrent.test (4): repl retention proven against a REAL
codethread (repl::init, synchronous runscript sends): inscope evaluation,
retention across submissions, n/ navigation retained, auto-create-with-
notice for a missing current namespace.
- punk::repl 0.5.2 fix: repl::start''s codethread seeding template
namespace-eval''d the full ns_current VARIABLE name, creating a stray
namespace of that name in every code interp (phantom child in n/ listings
of the nav namespace). Now ensures only the parent ::punk::nav::ns.
Subshell namespace carry-over semantics unchanged; pinned behaviourally
(mirrored template) plus a source-text guard, pending the planned
end-to-end piped subshell test (E3) at the shell level.
Verified: punk/ns 80/80, punk/nav 6/6, punk/repl 7/7 under Tcl 9.0.3;
nslist/navns/nscurrent green under 8.7. Console queries mocked throughout
(the render path consults get_size/get_tabstops). Project 0.12.33 +
CHANGELOG; tests AGENTS.md index updated.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New check pair in punk::lib::check, in the established style (G-076
console_deadspin exemplar: pure facts-in/verdict-out classifier
tclbug_nestedswitch_tracelines_signature + has_tclbug_* proc returning the
standard buginfo dict {bug bugref description level}, auto-surfaced through
the help tcl warning report via the info procs enumeration).
Unlike the version-gated checks, this one is a LIVE behavioural probe (safe
and cheap - no console interaction): a dynamically-defined proc with a
nested 4-word switch is enterstep-traced for inner arm 1 (affected split-
list index 1 - reports line 3) and the default arm (index 5, beyond the
command word count - reports line 2 correctly), matched against the
characterized wrong/right signature. Detection therefore flips
automatically on a Tcl runtime containing the upstream fix - no fixed_in
version variable needed. Probe layout note: a 2-arm probe would put the
default body at affected index 3 and hide the signature (both arms
mismark) - the middle arm exists to push default to safe index 5 (this
initially bit the probe itself, confirming the law once more).
Followup-when-fixed documented in the proc: re-verify with
scriptlib/developer/tcl_switch_traceline_repro.tcl, flip the
ns/cmdtrace.test GAP pins and fixed-canary, update the punk::ns::cmdtrace
argdoc caveat, note the fixed-in version. New canary test
cmdtrace_upstream_bug_check_canary asserts the check still reports the bug
- on a fixed Tcl it fails first and points at that workflow.
Verified: punk/ns 69/69 and punk/lib 37/37 under Tcl 9.0.3; cmdtrace.test
6/6 under 8.7; all has_tclbug_*/has_libbug_* procs exercised help-tcl style
without error; probe self-cleans (no temp proc/var residue).
punk::lib buildversion 0.4.3 -> 0.5.0 (new API procs = minor); project
0.12.32 + CHANGELOG; tests AGENTS.md index updated.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com