The zig version is now the first argument (default = the suite pin,
0.16.0) and each version installs into tools/zig-x86_64-windows-<version>
- the zip's own root folder name, so the old rename-to-tools/zig step and
its post-ExtractToDirectory lock retry/GC dance are gone. Installed-check
warns if the exe's reported version mismatches its versioned folder.
Documented limitations: dev builds (/builds/) and pre-0.14.1 releases
(old zig-<os>-<arch> naming) are not handled - the punkbin flat tools/
mirror path covers those if one must be pinned. The bash side stays an
honest stub with the same argument convention.
Rewrapped via scriptwrap::multishell (punk905_beta src script) ->
bin/punk-getzig.cmd (the untracked .ps1 twin byte-synced locally).
Verified all four paths through the polyglot: explicit present version,
no-arg default, existing-zip verify+extract (0.15.2 zip with no dir), and
the FULL network path (0.15.2 artifacts removed then re-materialized:
mirror latency selection -> download zip+minisig -> signature verified ->
versioned extract -> ZIG VERSION 0.15.2). G-096's remaining item is now
the final clean-checkout re-verification only.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The build016 experiment port lands in the tracked recipe (root_module/
createModule creation, addLibrary+linkage, .root_module.* method sweep,
linkSystemLibrary options arg, array_list.Managed, Io.Dir dir-walks with
b.graph.io, wrapfiletofile ported to the 0.16 entry/Io idiom). 0.14 support
deprecated per user direction; 0.14.1 remains archived on punkbin. Verified
on the pinned default (bin/tools/zig-x86_64-windows-0.16.0): build PASS,
shells 9.0.5, tcl-test parity 557/357/200/0 identical to the 0.14.1 build.
punk-getzig payload pins -> 0.16.0 (windows zip + linux tarball), re-wrapped
checkfile ERROR-free, ps1 twin refreshed. punkbin commit 54714d7 holds the
0.16.0 archive; push pending gitea recovery (server currently 500s).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Scriptset (src/scriptapps/bin) and the generated bin wrapper renamed; the
untracked bin/getzig.ps1 twin replaced by punk-getzig.ps1 (byte-copy of the
.cmd - launchability convenience for cmd.exe-or-powershell starts). Payload
improvements: self-references updated, and the ziglang.org release URL now
derives its version from the single $releasearchive pin (was a separately
hardcoded 0.15.1 vs the 0.15.2 archive). Re-wrapped via scriptwrap multishell;
checkfile ERROR-free (the two boundary-scan warnings are the documented-normal
polyglot ones). bin/AGENTS.md gains the punk- naming policy section
(exceptions: dtplite/sdx/kettle wrappers, getpunk; sweep of bits/runtime/
tclargs/selfsign is G-097).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Improvements from user review of the punk::ansi trial page:
- command index <nav> at page top (doctools-style jump list); hook to
display @package info above it when specs carry package_info (guarded -
key absent in older punk::args spec dicts)
- multiform commands: punk::args::usage renders all form synopses but only
the default form arg table (terminal UX expects i -form N) - the page now
adds a per-form ARG TABLE for each form that has arguments, trimmed at the
table-header separator so the command/description/synopsis panel is not
repeated per form (renderspace lines are colour-self-contained, so slicing
at a line boundary is safe); argument-less forms are skipped
- pre backdrop is now true black (page body stays dark grey):
overtype::renderspace overlay output emits explicit SGR 40 and example
helpers treat default background as the terminal backdrop - on black they
blend as in a terminal (proper fix = default-colour semantics, goal)
- row pitch line-height:17px (integer, just under the 17.85px inline
background height at font-size 15.36px) - the fractional 1.15em pitch put
row boundaries at fractional positions and showed periodic hairline gaps
through solid-bg runs
- explicit package require punk::lib (tstr placeholder resolution uses
punk::lib::undent; previously loaded only by transitive luck when usage
ran before get_spec)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Outcome of empirical seam/aspect testing of the ansi2html rendering against
src/testansi cp437 art (chrome + firefox, user-verified):
- punkdoc-mono.woff2 rebuilt with STOCK line metrics. The interim
normalize-to-win-metrics experiment (hhea/typo := win) is REJECTED and now
documented: it grows browsers'"'"' inline content area to 1.3213em, so at row
pitches below that every span'"'"'s background bleeds ~2.5px into neighbouring
rows - wrong-coloured bars under solid blocks. Kept as commented-out
normalize_line_metrics() in make_punkdoc_mono.py with rationale.
- font builds are now byte-reproducible: TTFont(..., recalcTimestamp=False)
keeps the source head.modified (two consecutive builds hash identically).
README records the new output sha256 and the reproducibility note, plus a
cell-geometry section for css authors (0.5859375em advance -> integer 9px
cells at font-size 15.36px; blocks paint the 1.3213em win cell) and the
settled art recipe: stock metrics + tight line-height:1.0 pitch +
transform:scaleY(1.3212890625) for terminal aspect (accepted trade-off:
minor residual sub-pixel seams; deterministic future fix would be
inline-block cell-grid emulation). Larger pitches (17.85/20px) tested and
rejected - stark row seams.
- punkargs_punknative.tcl: font-size 13px -> 15.36px (integer cell width -
fractional advances round differently at styled-span boundaries and seam
block/border glyphs); line-height stays 1.15 for text-oriented doc tables.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Repo policy is LF for text files; the as-downloaded copy had CRLF (also
tripped the fossil crlf warning on checkin).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
src/scriptapps/tools/fontprep/: pinned monospace web font for the punk-native
html doc pipeline, closing the glyph-coverage gap the probe identified -
unicode 16 octants (U+1CC00-1CEBF) and Symbols for Legacy Computing
(U+1FB00-1FBFF) needed by ansicat/textblock rendering are absent from
commonly-installed monospace fonts (even system Cascadia copies are commonly
pre-2404 and lack them).
- punkdoc-mono.woff2: glyph subset of Cascadia Mono v2404.23 VARIABLE ttf
(wght axis 200-700 kept - true bold from one ~80KB file; 1561 cmap
codepoints incl. full CP437 repertoire, box/blocks/geometric, braille,
legacy computing + octants). Coverage verified 157/160 against the measured
glyph inventory - identical to the full source font (misses are deliberate:
em-space + fullwidth forms are converter-normalization/fallback territory).
- renaming is REQUIRED by licence: Cascadia's SIL OFL 1.1 declares Reserved
Font Name "Cascadia Code" and subsetting is modification. Name table is
surgical: family records renamed, Microsoft copyright preserved verbatim
(OFL requirement), trademark record removed (a renamed copy must not assert
Microsoft's mark), OFL statement/url in licence records, provenance credit
in the description record.
- LICENSE-cascadia-OFL.txt (from the v2404.23 tag), punkdoc-unicodes.txt
(whole-block ranges with headroom), make_punkdoc_mono.py (fonttools subset+
rename script), README.md (full provenance: source/output sha256s, exact
command, regeneration steps). Python fonttools is one-time prep tooling
only - the doc build never invokes it; generators just read the .woff2.
Track licence in the G-063 inventory.
punkargs_punknative.tcl: new -assets option consuming the vendored font:
embed (default) = data-uri @font-face, fully self-contained page;
link = copy punkdoc-mono.woff2 beside the output and reference relatively
(shared+cached across a doc set); none = css stack only, with
warn-and-degrade when the asset is missing. font-weight 200 700 descriptor,
punkdoc-mono prepended to the fallback stack.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Two G-candidate prototypes under src/scriptapps/tools/ for punk::args as the
documentation source of truth (run against bootsupport modules with a plain
tclsh, e.g: tclsh punkargs_to_doctools.tcl punk::path out.man):
- punkargs_to_doctools.tcl: package's punk::args definitions -> doctools .man
(Tcl-standard [arg]/[opt] synopsis conventions by design - punk s-style is
out of scope for the doctools target). Covers @cmd summary/help, per-form
[call] synopses, argument detail lists in argspace order (leaders/options/
trailing values), constraint sentences (defaults/choices/ranges), id aliases
as cross-references. Validated via 'dtplite validate' (bin/dtplite.cmd);
punk::path trial output renders clean through the html/text/nroff engines.
- punkargs_punknative.tcl: doctools-free pipeline faithful to punk s-style.
html = punk::args::usage ANSI output converted via a minimal SGR->CSS
ansi2html (16/256/truecolour, bold/dim/italic/underline/strike/reverse) on
punk::ansi::ta::split_codes - candidate for a punk::ansi public api (also
the docs-screenshot enabler for ansicat/textblock output). markdown = GFM
with verbatim s-style synopsis fences + per-form argument tables.
-boxmap none (default) keeps faithful heavy box glyphs; -boxmap light maps
to the light set as a portability fallback.
Key findings baked into the code comments:
- css font stacks must be set on the pre element itself - the UA stylesheet's
'pre {font-family:monospace}' overrides body inheritance (cause of an
initially-misdiagnosed overlong-border rendering bug)
- glyph coverage probe over src/testansi + textblock::periodic/frames +
punk::args::usage (160 codepoints incl. unicode 16 octants and legacy
computing blocks): Cascadia Mono >=2404.23 covers 157/160; embedding or
referencing a pinned punkdoc-mono font remains the plan for doc-set output
since octant/legacy glyphs are absent from commonly installed fonts.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
'dev doc.validate' invokes a bare dtplite command which the repl
unknown-handler resolves via auto_execok on PATH - no dtplite executable
existed (only the legacy misnamed bin/dtplite_run.bat), giving
"invalid command name dtplite".
- src/scriptapps/dtplite.tcl: LF-converted (polyglot payloads are embedded
verbatim into the LF-only multishell output); fall back to the
project-vendored tcllib (src/vendorlib_tcl9/<arch>/tcllib*) when the
invoking tclsh lacks the dtplite package
- src/scriptapps/dtplite_wrap.toml: new scriptset config (tclsh nextshell
on all platforms)
- bin/dtplite.cmd: generated polyglot via
punk::mix::commandset::scriptwrap::multishell (checkfile-clean, LF-only)
- src/tests/shell/testsuites/binscripts/dtplite.test: artifact pins
(LF-only, checkfile, byte-identical round-trip re-wrap) + execution
usecases (usage error, validate good/bad file, validate directory tree,
html generation) - 8/8 pass under runtests
- AGENTS.md (bin, src/scriptapps): record the dtplite scriptset, its test
pin and the LF-only payload requirement
- punkproject.toml: 0.12.22 -> 0.12.23
Verified: 'dev doc.validate' in punk902z src validates all 64
src/doc .man files clean. The doctools pipeline remains interim -
punk::args is the intended doc source of truth.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- list -remote against an unreachable artifact server now warns and compares using the previously fetched sha1sums.txt instead of dying on an unhandled Invoke-WebRequest error (parity with the bash payload); no cached copy -> clear error + return
- the fetch path always fell through silently to a cached sha1sums.txt on download failure - it now announces "proceeding with cached copy" (behaviour unchanged, messaging explicit)
- fixed latent undefined-variable bug: the list -remote branch created the runtime folder with $container (only defined in the fetch branch) - now $archfolder
- bin/runtime.cmd regenerated (checkfile clean, roundtrip pin green 9 pass + 1 skip); verified live: unreachable PUNKBIN_URL -> cached-fallback table renders (tclsfe-x64 "Same version" against the punkbin pin), normal fetch path unchanged
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- bash/zsh payload gains list -remote parity with the powershell payload: local-vs-server sha1 comparison table (Same version / UPDATE AVAILABLE / not listed on server, plus remote-only entries), falling back to a cached sha1sums.txt with a warning when the server is unreachable (the powershell version has no cached fallback - candidate backport)
- both payloads: artifact server base url overridable via PUNKBIN_URL (mirrors/testing - also what makes the new feature testable offline)
- first real catch for the 512-byte label guard: the payload growth pushed the template's :exit_multishell target label across a boundary from its callsite (checkfile ERROR at wrap time); fixed with a documented byte-alignment spacer comment at the end of runtime.bash, and the resize-the-spacer workflow recorded in bin/AGENTS.md
- bin/runtime.cmd regenerated via scriptwrap (roundtrip pin green; multishell suite 9 pass + 1 skip on 9.0.3 and 8.7); runtime.bash syntax-checked under bash and zsh; windows list/use/run sanity re-verified
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- run no longer launches the last runtime alphabetically: resolution is PUNK_ACTIVE_RUNTIME env override -> bin/runtime/<platform>/active.toml (constrained single-key toml, written by the new 'use <name>' subcommand, marked with * in list, covered by the existing bin/* VCS ignores) -> sole installed candidate -> error listing candidates. First fetch sets active only when none recorded; later fetches never steal it. Stale active (file removed) reported with reselect guidance.
- bash/zsh payload fetch reaches checksum parity with the powershell payload: fetches sha1sums.txt, locates the stored hash, skips when the local copy matches, downloads to .tmp and installs only on sha1 match; sha1 tool detection (sha1sum/shasum/sha1/openssl) with refusal of unverified downloads when none present; optional runtime-name argument added (fetch <name>)
- fixes: powershell "stored hash from sha1sums.txt" printed an undefined variable ($storedhash -> $stored_sha1); bash MSYS branch invalid assignment (interp = ...); candidate listings for run/list/use exclude .tmp leftovers and non-runtime files (a stray .txt could previously be selected by run)
- runtime scriptset sources relocated to src/scriptapps/bin (proper home alongside getzig.*); bin/runtime.cmd regenerated via scriptwrap from the new location - roundtrip test path updated, suite green on 9.0.3 (8 pass + unix-gated skip), runtime.bash syntax-checked under bash and zsh
- verified live on windows: multiple-runtimes-no-active errors with candidates (previously silently launched tksfe-twapi-x64), use/list/run against tclsfe-x64 and env override to tclsh902z, fetch no-steal + first-fetch auto-set, checksum-match no-download path
- docs: bin/AGENTS.md documents the fetch/use/run contract and updated generated-polyglot workflow paths; src/scriptapps/AGENTS.md scriptset-home wording updated
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- new src/tests/modules/punk/mix/testsuites/scriptwrap/multishell.test (9 tests, green on tcl 9.0.3 + 8.7, unix exec case constraint-gated): scriptset wrap via the module-provided punk.multishell.cmd template (payloads + _wrap.toml fixture) - output produced, MULTISHELL magic line, payloads embedded verbatim, configured win32 nextshell present, LF-only endings, byte-identical re-wrap determinism; checkfile 512-byte label/boundary validation reports no label location errors for a fresh wrap AND for the committed bin/runtime.cmd; the runtime scriptset ROUND-TRIP pin - re-wrapping src/scriptapps runtime.ps1+runtime.bash+runtime_wrap.toml reproduces bin/runtime.cmd byte for byte (verified identical before pinning), so hand-edits to the output or unregenerated payload changes both fail; execution smoke - cmd.exe runs the polyglot and dispatches the powershell payload (windows), sh payload execution gated to unix (on windows the shell layer deliberately relaunches via the win32 nextshell)
- guidance strengthened so "fix bin/<name>.cmd" routes to sources: root AGENTS.md bin/ index entry now states the .cmd polyglots are scriptwrap-generated from src/scriptapps; bin/AGENTS.md gains a "Generated polyglot .cmd scripts - never edit in place" section with the 4-step fix workflow (edit payloads/toml, re-wrap with multishell -askme 0, heed checkfile ERRORs, commit source + regenerated output together); src/scriptapps/AGENTS.md documents the scriptset->bin/*.cmd relationship and regeneration command; tests index updated
- context: the polyglot technique is deliberately maintained despite fragility (user direction 2026-07-10) until hiding techniques close in the underlying languages - these pins are the guardrails
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com