The whole pipeline now lives in the zig recipe; Tcl remains the tool exactly
where a tclsh is guaranteed to exist - run by the FRESHLY BUILT suite shell
as build steps:
- New steps (native-host builds): smoke (static shell patchlevel; zip shell
patchlevel + attached tzdata/autoload), tklib / tcllib (their own installers,
batch, -pkg-path as a cached output dir installed into the prefix, + package
smokes incl withdrawn-Tk tooltip), tcllibc (critcl driving zig cc via the
tracked critcl_zig.config, module list parsed from tcllib's version.tcl,
pinned-zig dir prepended to PATH, + accel smoke), test-gate (tools/
test_gate.tcl - the parsed-totals gate vs expected_test_failures.txt,
-Dtestargs passthrough).
- Package landing moves into the recipe proper: thread pkgIndex.tcl
(build_tclthread), tk pkgIndex.tcl (build_tk), and the tclvfs script package
incl .in-template substitution + dll (build_tclvfs_shared
install_tclvfs_package) - all hooked to the install step.
- Step scripts: tools/test_gate.tcl, tools/suite_smoke.tcl, tools/pkg_smoke.tcl
(run under the built shell; assertions live in Tcl).
- Two windows-childproofing findings encoded: built-shell Runs execute the
CACHED artifact (no ../lib/tcl9.0 beside it) so each such Run gets
TCL_LIBRARY pointed at the source tree's script library (the zip smoke
deliberately excluded - its attached library is the thing under test); and
cached (non-side-effect) Runs spawn with stdout IGNORED, leaving the tcl
child without a stdout channel ('can not find channel named "stdout"',
critcl's logging) - such runs capture stdout to give the child a real pipe
while keeping caching.
- suite.tcl: thinned to the fossil dev flow - fetch live checkouts (git kind
now handled in the main loop for critcl's pin), stage the recipe, delegate
to the staged steps (run_zig_steps; 'test' delegates to test-gate). Default
-steps and the bootstrap default grow to the full pipeline short of
test-gate. critcl_zig.config + expected_test_failures.txt join both staging
lists. Docs updated (README two-flow section, sources.config two-surface
header, overlay section); .gitignore learns .zig-cache/ and zig-pkg/ (zig
0.16 extracts fetched packages into zig-pkg/ beside the manifest).
Verified (fossil flow): full pipeline PASS - suite_smoke static+zip, tklib
tooltip:2.0.4 under withdrawn Tk, tcllib md5/sha1/cmdline, tcllibc:2.0 with
md5-critcl-accel:1; 'suite.tcl test -testargs {-file http.test}' delegates to
the gate step (528/519/9/0 GATE PASS).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Blanket /src/buildsuites ignores removed from .gitignore and
.fossil-settings/ignore-glob; retired /vendorbuilds/ ignores removed with
them. src/buildsuites/_build remains ignored via the existing _build globs.
samplesuite1 sketch marked as such, buildprefix moved to the _build
convention (vendorbuild concept retired per user decision 2026-07-20).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
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
Stock tclsh treats any leading-dash arg other than -encoding as argv for an
interactive/stdin session: on a console it hangs at a prompt, with piped stdin
it exits 0 silently ignoring the supposed one-liner. Agents habitually reach
for -e (perl/python/node reflex), wasting time waiting on hung processes.
- root AGENTS.md User Preferences: document the misparse, the correct patterns
(temp .tcl file or script via stdin) and the defensive stdin-redirect habit
- .claude/settings.json: PreToolUse hook denying Bash/PowerShell invocations
of tclsh with -e, anchored to command position (start/pipe/semicolon/paren)
so prose mentions in commit messages or grep args do not false-positive;
corrective guidance returned to the agent
- .gitignore: narrow the .claude ignore so shared settings.json is tracked
while session-local files stay ignored
- .fossil-settings: ignore-glob hand-derived per the no-negation rule
(.claude/* wholesale + explicit fossil add of settings.json), exception set
in AGENTS.md updated; fossil extras under-ignore check verified empty
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
git tracked fossil's generated checkout artifacts (manifest, manifest.tags,
manifest.uuid - regenerated on every fossil checkin/checkout per the
versioned 'manifest' setting value 'rut'), which would churn as soon as
fossil commits begin. They are now untracked and git-ignored with
root-anchored patterns (nested manifest-named files elsewhere are real
content and stay tracked). Fossil control files (.fslckout/_FOSSIL_/
*.fossil) were already correctly git-ignored, and .fossil-settings/
.fossil-custom correctly git-tracked.
New .fossil-settings/AGENTS.md is the canonical home of the git+fossil
contract: which files each system must not track, the ignore-glob
derivation rules (no negation -> wholesale-ignore + explicit fossil add of
tracked exceptions; directory pruning; * crossing /; */ variants for
match-anywhere patterns; default dotfile skipping), and the verification
procedure any future "sync the ignores" request must follow (fossil extras
against git check-ignore, and a tracked-set comparison bounded to the
documented exceptions). The ignore-glob header now points there instead of
duplicating the rules; root AGENTS.md Child DOX Index gains the entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The dash-delimited launch package modes of built punk shells (dev/os/src/
internal, implemented in src/vfs/_config/punk_main.tcl) had no agent-facing
record. bin/AGENTS.md now documents the mode grammar and, in operational
terms, the src mode that matters for verifying working-tree changes:
exe-location-based project-root discovery, the source module paths it
prepends, package prefer latest (dev 999999.0a1.0 modules beating
kit-stamped snapshots), and how 'package present' distinguishes a src-mode
session from a plain kit launch. Also records the both-Tcl-generations
interactive verification convention (a Tcl 8.6-based shell plus the current
Tcl 9-based incarnation, deliberately not version-pinned) and the role of
the plain runtime kits under bin/runtime/ for punk-free probes.
Root AGENTS.md Child DOX Index gains the bin/ entry, and .gitignore gains
a !/bin/AGENTS.md negation alongside the other source-controlled bin items
(the /bin/* ignore is why no doc lived there before).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com