Evidence-checked continuation of the archive follow-on sweep:
- G-087 fauxlink link_as encoder => landed 2026-07-17: implemented in
fauxlink 0.2.0 (link_as + punk::args doc, upstream checkin 1e6b4ee8)
within the goal's own stage 2; the '=> open' marker derived from
Notes prose written earlier that same day, before stage 2 landed.
- G-139 linux-x86_64 lib-tier emission for punk9linux's tcllibc
siblings => goal G-140: G-140's delivered scope covers the item
exactly (tcllibc-tcl9-r1 emission, sibling replacement/supersede,
punkbin publication f94ffd2) and its record cites the G-139 flip
note as its origin.
Disposition-only edits per the goals/AGENTS.md Follow-ons contract.
goals_lint clean; goals_followons now 25 open / 20 goal / 13 landed /
2 declined (count also reflects c7470dac's G-165 mkimg-retirement
landing, committed independently of this pair).
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
zipfs_wrap.tcl (renamed from zipfs_mkimg.tcl, same CLI contract): payload zip
written by the driving shell's builtin tcl::zipfs::mkzip - convention-stable
across mkimg vintages (probed 8.7a6 vs 9.0.3: identical member tables/CRCs) -
with the prefix executable concatenated OUTSIDE the writer, plus an EOCD
archive-relative self-check per wrap (exit 9 on file-relative output).
build905.zig wrap lane updated (3 call sites, identifiers zipwrap_*); suite
README states the wrap contract; G-165 follow-on disposition => landed.
Verified: standalone wraps under both vintages mount/boot identically (840
members, base=prefix); suite make-zipfs/smoke/kit-family green - all 5
products probe archive-relative and boot (family_check plain/punk/punk-bi,
tclsh90szip smoke, tclsh90sprzip manual boot).
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
The G-159 retrofit recorded both of G-122's deferred items as '=> open',
but each had already been enacted by a drafted goal that cites G-122 as
its motivation:
- pure-Tcl zip decoder for the zipfs-less bake path => goal G-124
(punk::zip::unzip/members/archive_info, achieved 2026-07-26; make.tcl
extraction still consumes it and no zipfile::decode requirement
remains in the tree)
- refuse-to-deploy on missing tcl_library => goal G-125
(boot-precondition gate punkboot::utils::vfs_boot_library_report,
achieved 2026-07-27)
Disposition-only edit per the goals/AGENTS.md Follow-ons contract.
goals_lint clean; goals_followons report now 28 open / 19 goal /
11 landed / 2 declined.
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules + vfscommonupdate + bake ripple (native Tcl903 driver)
from the single-mechanism change-set ac19df2a: _vfscommon
punkboot/core.tcl regenerated from the 0.5.0 master; moduledoc::punkexe
0.5.0 -> 0.6.0 and moduledoc::punkboot 0.2.0 -> 0.3.0 version renames;
punk::mix templates modpod repacked carrying the layout _config sweep
(modpod-template copies + layout make.tcl copies via the established
sync channels). The same vfscommonupdate swept in promotions pending
from committed src work of the last sessions: commandstack 0.7.1,
punk::args 0.15.1, punk::auto_exec 0.1.1, punk::ns 0.9.2,
punk::tcltestrun 0.4.2, punk::zip 0.4.0.
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
All -help/--help flag interception withdrawn from the kit launcher and
make.tcl: the leading 'help' word is the ONE help entry (the punkshell
'i <cmd> ...' idiom). It felt like too many ways to do the same thing
and was already colliding - the experimental shellspy processor's own
-help/--help handling was shadowed by the dispatch intercept; it is
reachable again.
Launcher (boot core 0.4.0 -> 0.5.0, moduledoc::punkexe 0.6.0,
moduledoc::punkboot 0.3.0):
- 'help <subcommand> ?arg ...?' accepts and IGNORES trailing words, so
'help' can be prepended to an existing command line ('punk9_beta help
tclsh somefile somearg' now shows the tclsh usage instead of
confusingly falling back to the top-level table).
- Subject validation parses ONLY the subject word against a new
required-subject clone (script)::punkexe.launcherhelpsubject
(resolved_def -antiglobs {arg} -override subject -optional 0): the
display-shape clone let punk::args SKIP a mistyped optional subject
into the unconstrained arg row, silently rendering the top table
where a tabled choice error is wanted (exit 1).
- A leading '-help' falls under the unknown-first-argument refusal
(stderr usage answers it, exit 1); '<subcommand> -help' is the
subcommand's own argument: tclsh regains exception-free stock dash
parity, buildinfo refuses it like any argument (exit 2), a
parse-declared registration rejects it like any undeclared flag.
make.tcl: the wants_help subargs scan ('<subcommand> ... -help') and
the top-level/degraded-scan help-flag branches are removed, along with
the help_flags variable - 'make.tcl bakelist -help' now fails the
kitname choice gate exactly like 'make.tcl bakelist nonexistant', and
'make.tcl -help' the subcommand choice gate (exit 1), the usage error
itself carrying the documentation. 'make.tcl help <sub> <cmdline>'
dry-run behaviour unchanged.
Tests re-pinned to the revised contract (launcherhelp.test with a
kit_nodashhelp probe gate + trailing-args coverage, maketclhelp.test,
maketclcolour.test); punkexe subtree 152/148/4skip/0fail against
freshly baked zipfs + metakit kits; core copies byte-identical across
master/_vfscommon/layout/modpod-template channels.
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Every make.tcl zip-kit bake is to emit an ARCHIVE-relative kit regardless
of the driving interpreter's zipfs vintage (legacy file-relative mkimg in
8.7/9.0.0, fixed mkimg in 9.0.1+, or no mkimg at all): zip-kit assembly
moves to a single writer layer - punkzip (zig) when its binary is present,
punk::zip::mkzip (pure Tcl) as the always-available floor - with
tcl::zipfs::mkimg retired from the pipeline, and file-relative output only
via an explicit per-kit mapvfs.toml opt-in. Workstream order (user
decision): upstream punkzip root-strip/exclude enabling changes first,
then the punkshell seam. The detail file carries the driver-vintage probe
evidence (8.7a6=file, 9.0.3=archive), the upstream fix provenance (ticket
aaa84fbbc5, core 3d62ee540d 2024-12-05), the write-path benchmark (mkimg
11.4/35.9s vs mkzip 8.1/24.8s vs punkzip 6.7/20.0s at 132MB/396MB), the
drafting-time overlap survey and Related lines.
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
The closing-banner prefix check 'string match "$line_inner*"' treated
the raw test name as a glob pattern, so a test NAME containing glob
metacharacters (* ? [ ] backslash) never matched its own opening text:
the closing banner failed to close the failure section and every later
event including the summary line was swallowed (the G-161 wedge class;
latent, unexercised in the corpus). The check is now an exact byte
prefix compare (string equal -length) - identical semantics for ordinary
names, and an empty line_inner keeps the historic match-everything
behaviour. New parsetestrun-globname-7.0/7.1 pins: 8/8 green tclsh90
single+multi-process and tclsh86, parser dir 10/10.
Landed directly at user direction from the archived G-161 Follow-ons -
disposition flipped to landed in the same change-set (the sanctioned
archived-file edit). runner/AGENTS.md parser coverage bullet updated.
CHANGELOG + punkproject 0.51.2.
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- User Preferences: lean towards larger commits when splitting adds complexity (a goal drafted from discussion during another goal''s implementation may land in the same commit or one goals-tier commit; no partial-hunk staging gymnastics for per-goal purity); corollary - agents OFFER to commit at seams (green test gate, coherent sub-change, before a new concern) rather than letting the uncommitted set grow past the natural split
- Commit Conventions: pointer bullet to the new preference
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- new goal (user-drafted 2026-08-04): when the valmin reservation seats a word that literally names a declared required option into a required value slot and the resulting optionmissing stands in the G-152 viability probe, re-parse with the stolen word(s) consumed as the option they name; pure end-of-input exhaustion after that re-seating grants viable-incomplete. Runtime seating unchanged (the trailing-flag-as-value rule is load-bearing, pinned by flagvalues_plain_then_dash)
- surfaced by the G-150 batch + independent second-session review: 'i hash -t' classes the test form '(not viable)' although 'hash -t foo' is valid - a false negative, GAP-pinned in cmdhelp.test (owned by this goal; the pin flips at achievement)
- overlap survey in the detail file (G-044 consumer; G-152/G-150 archived relations; args/ns family anchors dismissed as unrelated mechanisms)
- G-044 Notes: records G-164 as the probe-layer answer to G-152's "completion consumer lookahead" note for the valmin-reservation class
- goals_lint clean (82 active, 82 archived)
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
Acceptance met in full (evidence in the archived detail file's Progress): 'i ::punk::auto_exec::hash -r' renders only the rehash form's usage and '-d <name>' only the delete form, driven by the declaration (bare punk::args::parse withid selects flag-led forms uniquely via the show_or_set name's -regexprefail {^-}; no hash-handler involvement); runtime behaviour otherwise unchanged (dash-led name needs an explicit flag form - accepted cost); ensembles/single-form/no-word invocations render as today. The goal reduced to its declaration half - cmdhelp's G-041 advisory-parse candidacy already narrowed on a unique selection.
- index entry -> GOALS-archive.md; detail file -> goals/archive/ with Progress evidence and Follow-ons (handler multi-name -t missing-name defect => landed 2026-08-04 by user fix; selection-soundness sweep of other definitions => open)
- activation-freshness xref re-run at activation recorded; reference sweep at archive: no live-tier mentions, no xref bridges lost; goals_lint clean
- code/tests landed in the preceding commits (auto_exec 0.1.1, ns 0.9.2, cmdhelp.test 45/45); punkshell 0.51.0
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- 'i <command> ?word ...?' form narrowing for flat multi-form commands (G-150): punk::auto_exec::hash's declaration is selection-sound, so 'i hash -r' renders only the rehash form's usage and 'i hash -d <name>' only the delete form, driven by the declaration through cmdhelp's G-041 advisory-parse candidacy; no-word, ambiguous and no-match lines keep the whole-command render
- punk::args 0.15.0 @values -flagvalues (G-150 follow-on): opt-in dash-led-words-as-values seating; consumed by hash's tightened help form
- known issue recorded in the entry: the test form's '(not viable)' for 'i hash -t' is a false negative (valmin reservation steals the flag word into the required value slot) - GAP-pinned, owned by G-164
- modules: auto_exec 0.1.1, ns 0.9.2 (documentation-only), args 0.15.0; pins: cmdhelp.test 45/45, flagvalues.test 9/9
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- auto_exec 0.1.1: hash's show_or_set name value carries -regexprefail {^-} - a bare punk::args::parse of a flag-led line now selects its flag form uniquely instead of 'Ambiguous arguments ... show_or_set, <flag form>' (show_or_set swallowed flag-like words as plain names), so cmdhelp 'i hash -r' narrows to the rehash form with no handler involvement; runtime behaviour unchanged (the handler's first-word switch already rejected dash-led names; at the declaration level they now need an explicit flag form - accepted cost). Help form tightened (user direction): -anyopts dropped so --help must lead, and @values -flagvalues 1 (punk::args 0.15.0) makes trailing words of any shape consume as ignored values - a flag-led line no longer marks the help form viable via adhoc-option seating. Handler fix (user-landed): the multi-name -t missing-name branch printed "$hash: nm: not found" (undefined variable) - now "hash: $nm: not found"
- ns 0.9.2: documentation-only - cmdhelp's subcommand argdoc now states the multi-form narrowing contract explicitly (no code change; the G-041 advisory-parse candidacy already narrowed on a unique selection)
- cmdhelp.test: G-150 pins - flag-led narrowing on -r/-d, bare-parse selection incl -t/plain/empty lines, the dash-led-name noformmatch cost, no-word/unknown-flag/ambiguity whole-render fallbacks, runtime-unchanged hash behaviour, help-form narrowing and dashword swallow, and the no-false-viable-help pin; plus a GAP pin of the valmin-reservation false negative in the G-152 viability verdict (owned by G-164, proposed) - 45/45 green
- src/tests/modules/AGENTS.md: index clause for the new coverage
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- a @values section may declare -flagvalues 1: an unmatched dash-led word in option position is consumed as a trailing value instead of raising invalidoption (declared options still match first; the '--' end-of-options marker is unaffected; off by default) - VAL_FLAGVALUES on the form dict (template default false; @values compiler key, boolean-validated at resolve time) short-circuits the unmatched-dash-word fallback in the parse engine
- motivation: '--help'-style forms robustly swallowing ignored trailing words of any shape - previously such a word seated as a value only positionally (at end-of-input via the valmin reservation, or within a bounded valmax) and errored 'Unexpected option' otherwise ('{--help -t foo}' on the unconstrained shape)
- in-tree consumer: punk::auto_exec::hash's help form (next commit); documented in the module header notes
- tests: new flagvalues.test (9 tests - seating matrix, declared-option precedence, off-by-default contrast, optionmissing after value seating, key validation); args subtree 271/271 green
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- known_renamers and debug are now info-exists guarded like the rest of the
module state (all_stacks, renamer_command_tokens, token_implementations) -
a module re-source refreshes proc definitions only, no longer resetting
them while stacks/tokens survive
- previously the reset stranded live stacks: the removal forms gate on
known_renamers membership, so surviving records' renamers became unknown
and removal errored
- contract documented in commandstack::help; pinned by
commandstack_reload_preserves_state
- suite 41/41 on tclsh90 (9.0.3) + punk86 (8.6); packagepreference consumer
suites 6/6 on both; minted modules/commandstack-0.7.1.tm
(bootsupport/vfscommon promotion left to the next cycle, as with 0.6.0/0.7.0)
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
Acceptance met in full (evidence in the archived detail file's Progress): the named invocations punksys -e {puts hi} / punk902z script -e {puts hi} and the full matrix (piped and unpiped stdin, no-arg usage error on both surfaces, errorInfo + exit 1, argv0/argv, result echo, tclsh -e stock-parity boundary) verified by hand on the baked kits; scriptexec.test + launcherhelp.test 49/49 green. Index entry -> GOALS-archive.md, detail file -> goals/archive/ with Progress evidence and a (none) Follow-ons section; G-141/G-158 reference-sweep achieved markers; no xref bridges lost. goals_lint clean.
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- app-punkscript 1.0 -> 1.1: 'script -e <script> ?args...?' - ::argv0 '-e', trailing args in ::argv, errorInfo to stderr + exit 1 on error, usage error + exit 1 when no script follows (never interactive fall-through, never stock's argv-swallow + stdin-read misparse); stdin never read by the form itself; a non-empty final result is echoed (stdin-form one-shot ergonomics, so return-valued one-liners like 'dev projects.work *x*' emit)
- boot core 0.3.0 -> 0.4.0: a top-level first argument of exactly '-e' reclassifies to 'script -e' ahead of the G-032 unknown-first-arg refusal on script-default kits (tool-style kits keep '-e' routed to their processor; '<punkexe> tclsh -e ...' keeps deliberate stock parity per G-118); the unknown-first refusal hint and the degraded plain help now name the -e forms
- moduledoc punkexe 0.4.0 -> 0.5.0: (script)::punkexe::script declares the oneliner @form (both forms explicitly named - punk::args renames _default to the FIRST named @form args-included); top-level prose documents the reclassification; tclsh boundary text points at the live forms
- tests: scriptexec.test gains 10 -e pins (both surfaces, argv0/argv, piped stdin read+unread, no-arg usage error on both surfaces, errorInfo+exit 1, result echo, tclsh -e stock-parity boundary); launcherhelp.test pins the refusal hint's -e pointer; 49/49 green on the rebaked punk902z/punksys/punk86 (stamps boot_core=0.4.0); the named acceptance invocations and the full matrix also run by hand on the baked kits
- DOX: -e bullets in src/vfs, src/lib, src/tests/shell and bin AGENTS.md; root AGENTS.md tclsh -e pitfall parenthetical now records the live punk-kit forms + the ad-hoc 'src script -e' option; README script-subcommand bullet; ARCHITECTURE.md entry-point/script/tclsh sections (G-077 leaves the in-flux list)
- CHANGELOG + punkproject 0.50.0
Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai
- pop_rename renamer ?command? - pop the renamer's topmost stack entry and
return the removed record (searched across live stacks when no command
given; entries on multiple commands are an ambiguity error)
- remove_renamer renamer - remove ALL of a renamer's entries across every
live stack (the unload-my-package form); returns removed records keyed
by command
- restore_original command - unwind the whole stack to the original
implementation regardless of renamer; registers stack-evidenced renamers
into known_renamers so it is not gated by state loss (module re-source)
- all three route through remove_rename's re-linking/token-map machinery;
Rename_stack-parked stacks are invisible to the renamer-wide forms
- suite 40/40 on tclsh90 (9.0.3) + punk86 (8.6); packagepreference
consumer suites 6/6 on both; minted modules/commandstack-0.7.0.tm
(bootsupport/vfscommon promotion left to the next cycle, as with 0.6.0)
Assisted-by: harness=opencode; primary-model=opencode/kimi-k3; api-location=unknown
The '---- errorInfo: ' / '---- errorCode: ' prefixes are 16 characters;
parse_testrun captured from index 15, so every captured value led with
the prefix's trailing space. Capture now starts at index 16 -
report-shape normalization only (continuation errorInfo lines were
always raw and are unchanged). parsetestrun-multiline-error-3.0 pins the
normalized shape (errorcode exact, errorinfo anchored) instead of
trimming/tolerating; 6/6 green tclsh90 + native tclsh 8.6.
Landed directly at user direction from the archived G-161 Follow-ons -
disposition flipped to landed in the same change-set (the sanctioned
archived-file edit). CHANGELOG + punkproject 0.49.7.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance met in full (evidence in the archived detail file's Progress):
synthetic + e2e parser suites committed and green both runner modes and
both Tcl generations; full-suite parity PARITY ok in both modes;
src/tests/AGENTS.md relaxed to style guidance. Index entry ->
GOALS-archive.md, detail file -> goals/archive/ with Progress evidence
and three structured open Follow-ons (single-line banner anchoring,
glob-metachar closing-banner match, errorInfo/errorCode leading space).
Reference sweep: no pending-tense live-tier references existed;
goals_lint clean (83 active / 80 archived); goals_followons registers
the three open items; goals_xref reports no lost bridges.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- runner/testsuites/parser/multilinebanner.test + fixtures/
multilinedesc.testfixture: the deliberately failing fixture (multi-line
description; non-.test extension so default *.test discovery never sees
it) is run through real child runtests.tcl invocations in BOTH modes and
the json report asserted as exact-text probes: failure entry FAILED with
result_was/result_expected populated, trusted summary
(summaryline_detected 1, totals 2/1/0/1). 2/2 green on tclsh90 and
native tclsh 8.6; runner subtree 30/30 under -jobs 4.
- runtests.tcl: punk::tcltestrun require floored at 0.4.0- (tolerant
parser + result_expected capture; kit-fossil rejection floor).
- parsetestrun.test: explicit punk::args + punk::lib requires - the lean
-jobs child exposed tcltestrun's load-time punk::args dependency (about
section calls punk::args::lib::tstr/resolved_def at source time; every
other context preloads punk::args). Declared at test level per the
established lean-children convention.
- src/tests/AGENTS.md: single-line-description rule relaxed to STYLE
guidance (multi-line tolerated since punk::tcltestrun 0.4.0, boundary
documented); floors bullet gains punk::tcltestrun 0.4.0-; runner index
line mentions output parsing.
- runner/AGENTS.md: parser characterization pair documented (fixture
extension convention, two-children cost note).
- modules/AGENTS.md commandstack bullet + commandstack.test NOTE comment:
hard contract wording updated to style guidance (G-161).
- CHANGELOG.md + punkproject.toml: 0.49.6.
Full-suite parity before/after the parser change verified in BOTH modes
with scriptlib/developer/runtests_parity.tcl (new parser dir excluded from
the after-runs to keep the file set identical): PARITY ok, 126 files,
1422/1400/20/2 both sides. Inclusive full run: 1430 total, same two
pre-existing failing files (core exec.test, punkboot offsetstyle.test),
0 warnings.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl modules + make.tcl bootsupport outputs batch (punkcheck-managed):
- punk/tcltestrun 0.3.1 -> 0.4.0 (the G-161 multi-line banner parser -
runtests.tcl's parent loads the bootsupport copy, so this promotion is
what puts the tolerant parser in front of the runner)
- punk/console 0.8.0 -> 0.8.1 and shellfilter 0.2.4 -> 0.2.5: already
committed in src/modules and already promoted into _vfscommon
(ac032b96/8864e5ce); this bootsupport run swept the snapshots current
- punk/mix/templates-0.2.0.tm re-packed by the mint (modpod payload
refresh, no source change)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
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
User-directed activation (proposed -> active, index + detail mirror).
Activation-freshness survey (goals_xref score G-161) recorded in the detail
file Notes: no related live goals - every overlap pair is unlinked with zero
path intersection (lexical noise only; interval-drafted G-163 unrelated).
goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New goal (user-approved wording): punkshell exit paths on unix ttys restore
blocking on the shared tty file description and drain pending stdout/stderr
(bounded best-effort) before teardown - closing the tclIO behaviour where
stdin's non-blocking read windows make stdout non-blocking underneath,
'flush' silently no-ops once a background flush is scheduled, and TclInExit
discards EAGAIN'd buffers (measured 2026-08-03: 161/5000 lines survive exit
on a throttled WSL pty; ~498KB pending after a 'successful' flush). Guard
homes in punk::console, invoked after the G-038 eof-restart decision point;
acceptance includes complete delivery under a slow reader, bounded exit under
a dead reader, unchanged windows/piped behaviour, ARCHITECTURE.md exit-section
documentation, and a unix-pty-gated pin. Related: G-038, G-013, G-011, G-090
(+ archived G-036 lineage).
goals_lint clean; overlap survey recorded in Notes.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New goal (user-approved wording): 'make.tcl bakelist' gains per-kit payload/
runtime freshness verdicts answering "would a rebake change this kit?" without
baking - punkkit-stamp.toml schema 2 records content digests of each kit's
assembly inputs (payload vfs manifests via the assembler's existing per-entry
CRCs, runtime artifact digest, resolved mapvfs declaration, bake schema) and
bakelist compares them against the current tree. Verdicts degrade per kit to
'n/a (<reason>)' (pre-digest stamp, unreadable container, mk4 driver
unavailable) without aborting the listing; zip kits read pure-Tcl via
punk::zip, mk4 kits only where a metakit driver loads. Context records the
existing deployed column's real (narrower) role: deploy-hop integrity for the
locked-exe trap. Related: G-131, G-158, G-023, G-147, G-137.
goals_lint clean; overlap survey (goals_xref paths + score) recorded in Notes.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
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
Activation survey re-run per the freshness rule: no goals drafted since
G-160's drafting commit; top overlap remains G-035 (already Related:).
G-108/G-090 next scores are lexical-only (debug/stack vocabulary), no
new Related: lines. Survey note recorded in the detail file.
Claude-Session: https://claude.ai/code/session_01TNn3C58Cpekt3CsZNLCqvR
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
goals/AGENTS.md: Follow-ons contract - ## Follow-ons section as the last
section of archived detail files, line grammar with closed disposition
vocabulary (open | goal G-<id> | landed YYYY-MM-DD (<where>) | declined
YYYY-MM-DD (<why>)), disposition-only updates sanctioned as the one edit
to archived files (same work unit that acts on the item), archive-flip
reference sweep gains step (c) emitting the section. GOALS.md: v4 front
matter + version entry, achieved-flip and acting-on-a-follow-on
maintenance rules, authoring-workflow disposition-flip duty.
GOALS-archive.md: frozen-file carve-out wording. goals_lint.tcl: grammar
findings (malformed column-0 Follow-on line, disposition naming a goal in
neither index) - fixture-verified both fire. New goals_followons.tcl:
advisory disposition report grouping open items first + vocabulary-
without-section flags; real-archive baseline 30 flagged files (retrofit
is the next change-set).
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Activation survey re-run per the freshness rule: G-160/G-161 (drafted in
the interval) show no scope overlap; standing relationships unchanged
(Related: G-156). Survey note recorded in the detail file.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Two user-approved proposed goals from the 2026-08-03 commandstack
characterisation arc (git 145e785c):
- G-160 commandstack hygiene pass: fix the suite-pinned defects (tokenid
stuck at 1 with duplicate-token dispatch bypass, unreachable
get_IMPLEMENTOR builtin branch, debug arg validation, stray bare puts,
Delete_stack live-rename recursion, packagepreference rename/renamer
guard key) and land the ergonomics items (did_rename record key appended,
-renamer placement errors, O(1) token dispatch, delegation helper,
Rename_stack/get_stack parking retrievability, known_renamers defaults
reconciliation). Acceptance keyed to the _GAP_ test flips; overlap survey
surfaced only G-035 (sibling surface on packagepreference, related-noted).
- G-161 tcltestrun failure parsing robust to multi-line test descriptions:
the parser currently misses multi-line opening banners, misreads the
closing banner as an opener and swallows all later events including the
summary line; goal makes it tolerant so the src/tests/AGENTS.md
single-line-description contract can stand down to style guidance.
Overlap survey: no intersecting live goals.
goals_lint: clean (84 active-index goals, 77 archived).
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 G-135 checker's directory walk skipped only {.git _build} - authored
2026-07-28, before the G-155 _build -> _mint/_bake workdir renames. A
default 'check' sweep would descend any _mint staging or _bake kit trees
under its territory (src/ minus buildsuites, scriptlib/, goals/) and
could classify staged asset copies. Skip set is now
{.git _build _mint _bake}; usage comment updated to match.
Verified: selftest 16/16 passed; default check sweep 9/9 verified.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com