goals_xref score re-run at activation: no relationships beyond those already
recorded (G-028's overlap is lexical - the probe reads assembled build
images, not deployed exes, so no locked-exe interplay; G-131/G-127 already
carry Related coverage). goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
bin/AGENTS.md gains the user's 2026-07-29 principle: the multishell polyglot
mechanism exists to serve BOOTSTRAPPING (no-tclsh/no-toolchain cold start -
punk-runtime, punk-getzig) and, being complex and potentially fragile long
term, is not to be expanded unnecessarily - capabilities that only run with a
tclsh present belong in-tree behind make.tcl. G-006's Notes record the
corresponding fetcher-shape leaning (non-contract): no punk-gettool polyglot;
the make.tcl-integrated downloader the goal's Approach already leans toward is
the indicated shape (build-tool fetching always has a tclsh - make.tcl IS the
consumer), with punkres on the punkbin tools tier noted as the first concrete
artifact the channel would serve. Doc-only, non-shipped surfaces - no version
bump.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Post-push verification against the live server: punkres-x86_64-windows-0.3.1.exe
fetched from gitea punkbin, sha1 matches the published sha1sums row and the
staged value (166cd176...), fetched binary runs. Every acceptance clause is
satisfied (full evidence in the detail file's flip entry: post-hoc stamping
with tool-self read-back + twapi cross-check, boots, convergence, both
section shapes, file-relative refusal/consented preserve crc-verified,
zip64/multi-disk refusal, WSL non-windows e2e with host recorded, seam
selection + parity + zig-optional degradation, distribution both ways now
LIVE, RT_VERSION-ready tree handling, licensing/provenance).
Flip mechanics: detail Status achieved 2026-07-29 with evidence appended;
index entry moved to GOALS-archive.md (record format incl. that file's
arrow convention); reference sweep - G-127 cross-host mention, G-134
Related line and G-101's container-review rider gain achieved/archive
markers, PROVENANCE.md's explicit detail path repointed to the archive.
goals_xref: no live pairs were bridged solely by G-128. Archive MOVE of the
detail file follows as a separate pure-rename commit (Doc Restructures
move/edit separation).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Distribution convention (recorded in src/tools/punkres/PROVENANCE.md): the
tool publishes to the punkbin tools tier as
win32-x86_64/tools/punkres-x86_64-windows-<ver>.exe (arch-os-version beside
the zig archives; immutable), integrity via that tier's sha1sums.txt.
0.3.1 STAGED as punkbin commit 1b471fc (sha1 166cd176..., built by the tool
step from vendored 0.3.1/f0af880, all other sha1sums SAME) - push is
maintainer-gated per punkbin AGENTS.md, and agents never push. Route
documented in bin/AGENTS.md; the seam's skip notice names both remedies
(build from vendored source, or fetch the prebuilt artifact). Demonstrated
in the program-files checkout: artifact placed as bin/punkres.exe reports
0.3.1 and make.tcl tool list reads it CURRENT against the vendored tree.
Reproducibility note recorded: zig builds differ across invocations in the
PE-header timestamp region - the published sha1 pins THE artifact.
Goal Progress: increment 1f; the only remaining acceptance item is the
maintainer push making the fetch URL live - achieved flip flagged for
confirmation at that point. punkres.test 8/8 re-verified.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-reported: './punk-getzig.cmd' from a spaced checkout failed with
'C:\repo\jn\program: The term ... is not recognized' while punk-runtime
worked. Root cause: punk-getzig_wrap.toml still used the pwsh '-c'
command-string launcher, which tokenizes a spaced script path - punk-runtime
received the 'cmd.exe /c powershell ... -File' fix during G-119 (its wrap
toml carries the comment) and punk-getzig never did. Adopting the same
launcher surfaced three latent payload issues, all fixed in
src/scriptapps/bin/punk-getzig.ps1:
- Resolve-Path -RelativeBasePath is pwsh 7.4+ - replaced with the
Push-Location + -Relative spelling (PS5-compatible)
- Invoke-WebRequest without -UseBasicParsing NullReferences on PS5 (IE
parsing engine); all three call sites fixed, with progress suppressed
around the large distribution download (PS5 -OutFile slowdown)
- Invoke-Expression "$zigexe version" splits spaced paths under ANY
powershell (latent even on pwsh) - both sites now use the call operator
Payload growth pushed :exit_multishell across a 512-byte boundary; the
punk-runtime-style '(512B spacer)' comment added to punk-getzig.bash and the
polyglot regenerated (checkfile ERROR-free). Verified in the
'C:/repo/jn/program files/punkshell' checkout: full fetch (community-mirror
latency ordering, local punkbin mirror, minisign verify, extract, ZIG
VERSION: 0.16.0) and the already-installed branch; main-repo argless run
clean. Sources and regenerated bin/punk-getzig.cmd committed together per
the wrap workflow (no roundtrip pin exists for punk-getzig - candidate noted
in the completion report).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Progress increment 1e: route (a) hermetic cross-compile from the pinned
windows zig ran tool-level (linux punkres stamps punk91, full read-back on
linux) and seam-level (make.tcl bake punkluck86 under the WSL tclsh 8.6.14
embedded via punkres on a linux host - the exact cross-host gap this goal
closes); route (b) fetched linux zig 0.16.0 and ran the suite natively
(33/33 after the usage-pin fix) with a byte-identical stamp from the
natively-built binary. Windows confirmed both artifacts (icon bytes, twapi
inside the stamped kit, boots). Cross-host determinism recorded: linux and
windows post-hoc stamps byte-identical; the 4-byte CheckSum delta vs the
fleet artifact is the stub-time-vs-whole-file ordering artifact, both arms,
loader-ignored. Remaining acceptance item: punkbin publication route only.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Upstream f0af880 (f97eda2 + version-pin fixup): the first native linux test
run (WSL Ubuntu 24.04, zig 0.16.0, route-b of the e2e) surfaced the usage
pin's hardcoded punkres.exe argv0; the pin now splices EXENAME comptime and
the suite is green on BOTH platforms (windows 33/33 verified here from the
vendored tree; linux run recorded in the goal detail). bin/punkres.exe
rebuilt via the tool step (0.3.1).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Closes the observed UX gap (G-128 detail, program-files checkout findings):
fetch reports an active runtime, but bakes reference the suffixless WORKING
name that only 'use' materializes - so a first fetch left bakelist reading
runtime=missing with nothing pointing at the next step. Both payloads (ps1 +
bash, parity wording) now print
note: bakes and projects reference <working> - materialize it with:
punk-runtime use <artifact>
after fetching an -r<N> artifact whose working name is absent, and stay
silent once it exists (the downloads-never-bind rule is unchanged - fetch
still materializes nothing).
Sources edited under src/scriptapps/bin and bin/punk-runtime.cmd regenerated
via scriptwrap multishell (-force 1; checkfile ERROR-free, 4 normal
possibly-bogus warnings) - committed together per the wrap workflow;
runtimecmd_roundtrip byte-identity passes. New pin
runtimecmd_fetch_materialize_hint in runtimecmd_freshness.test (11/11, ~+5s:
hint present on both payloads via the fixture server, absent after use via
the cmd route). Live-verified against the real punkbin server from the
spaced test checkout: hint fires on the no-download path too, silent with
the working copy present.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punkres.test gains punkres_spaced_paths (8/8, ~3s file total): the store
fixture copied into a directory AND filename carrying spaces, stamped with
the consent flag and read back byte-identical - characterizing the Tcl-list
exec quoting the seam relies on (kit_icon_embed_punkres builds its command
with list/lappend and evaluates it via catch of a pure list: word-per-element,
no {*} needed, no re-substitution).
Goal detail records the live evidence from the user's test checkout at
'C:/repo/jn/program files/punkshell': bake punk9_beta there embedded via
punkres with every path spaced (kit wears PUNKSHELL, boots, bakelist
deployed=current), punk-runtime.cmd fetch/use polyglot fine under spaces,
tool build via PUNK_ZIG override; plus the runtime-store finding - fetch
downloads only the -rN artifact, materialization of the mapvfs-named working
copy needs 'use <full-artifact-name>' (suffixless use selects existing
runtimes only), bakelist reads runtime=missing until then - with candidate
UX improvements flagged for the user.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Forced fleet rebake (user-directed): all ten win32 kits now carry the embedded
PUNKSHELL group icon via punkres, verified per kit (punkres list, sidecar
icon_group=PUNKSHELL + embedding=punkres, extract-ico byte-identical spot
check) and booting (incl. metakit punksys 8.6.13 / punk86 8.6.17 and
punk902z 9.0.2). punkmagic excluded (runtime absent - keeps its old icon and
_build cache); punkshell902 linux = not applicable.
The first fleet pass surfaced a real shape: mingw-built runtimes (tclsh902z,
tclkit-win64-dyn family) keep COFF symbol/debug tables AFTER their sections,
the extraction head carries them, and punkres correctly refused those stubs
as data-classified overlay. Measured against twapi-era artifacts: Windows'
EndUpdateResource has always silently STRIPPED exactly those bytes at
stub-stamp time (leaving PointerToSymbolTable dangling) and the kits work -
so punkres 0.3.0 (upstream dca8634, re-vendored, 33/33) encodes the
distinction: -drop-opaque-overlay DISCARDS expendable trailing data and
zeroes the orphaned symbol-table header fields, vs -allow-opaque-overlay
which RELOCATES a real self-locating payload; conflicting flags rejected;
drop is inert on zip overlays. The seam's punkres arm passes -drop
(twapi-arm-equivalent stub hygiene; bin/AGENTS.md documents it).
Recovery note: a 10-minute foreground timeout killed the first 3-kit rerun
during deploy - stale src/_build/.punkcheck.lock removed after a dead-pid
check per the recorded procedure; the completion bake deployed the
already-wrapped kits. Full punkexe suite 83 tests 0 failed; goals_lint +
architecture_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
RT_GROUP_ICON name policy (user decision 2026-07-29): kit_icon_process derives
icon_group from the icon FILE's uppercased rootname (RC convention) -
punkshell.ico -> PUNKSHELL for the default icon and per-kit overrides alike -
and passes it to whichever mechanism embeds. punkres arm uses set-icon -group
(punkres 0.2.0); kit_icon_embed_twapi gains the matching optional
group_override (name only - language adoption unchanged) so the arms stay in
parity. Replaces the retained stub-lineage names (punk91 "SFE", suite kits
"TCLSH"); already-deployed kits keep theirs until their next natural rebuild
(the policy is not in the punkcheck source set).
Sidecar gains icon_group (recorded whenever the icon file exists);
bin/AGENTS.md format doc + ARCHITECTURE.md updated, architecture_lint clean.
Live-verified on punkluck86 rebakes: punkres arm and twapi arm (TCLLIBPATH
route) both emit RT_GROUP_ICON "PUNKSHELL" lang 1033, extracted icons
byte-identical between arms; sidecar icon_group=PUNKSHELL; final deployed
state punkres-stamped and booting. Full punkexe suite 83 tests 0 failed.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punkres 0.2.0 @ upstream c0eb919: set-icon -group <id|name> overrides the
adopted RT_GROUP_ICON name (stored as given, case-insensitive lookups; lang +
codepage adoption unchanged; re-stamps without the flag adopt the renamed
group - convergent). Vendored tree tests 32/32; bin/punkres.exe rebuilt via
the tool step; punkexe punkres.test 7/7 unchanged. Seam group-name DEFAULT
deliberately not changed - proposal (icon-filename-derived name, twapi arm
gaining the same override for parity) outstanding with the user.
Goal records: metakit 'kit'-shape acceptance clause recorded satisfied-for-now
(user decision) with a rider in G-101's Notes asking its container decision to
include a post-hoc stamping-support review; BSD-2-Clause confirmed. The
2026-07-29 environment finding is CORRECTED: the twapi arm's availability is
launch-cwd sensitivity (make.tcl adds src/vendorlib_tcl9/<host> to library
paths only when startdir tail is 'src'), not a missing root vendorlib tier as
commit 5e9f1c75's message stated - root vendorlib_tcl9/ never exists.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
src/make.tcl kit icon seam (G-057): mechanism selection is now punkres-first -
kiticon::punkres_available (memoized; binary presence at bin/punkres(.exe) is
the selection signal) + kit_icon_embed_punkres (exec wrapper; punkres verifies
its own output). twapi arm unchanged as fallback; when NEITHER serves the skip
notice combines both reasons and names the 'make.tcl tool build punkres'
remedy. Sidecar embedding value gains 'punkres' (bin/AGENTS.md format doc,
ARCHITECTURE.md kit-icon bullet updated; architecture_lint clean).
Live-bake fallback matrix on punkluck86 (win32-ix86 = PE32 arm live): punkres
present -> embedded via punkres, kit boots + smoke OK; punkres absent + twapi
loadable -> via twapi; both absent -> unavailable with combined notice,
embedding none (exact pre-G-128 degradation). Live parity: both arms' baked
kits listing-identical (codepage host-ACP noise finding recorded in the goal
detail) with byte-identical extracted icons.
New src/tests/shell/testsuites/punkexe/punkres.test (7/7 under the
tclsh9.0.5-punk runner; self-gates on bin/punkres + store fixture): overlay-
unsafe refusal exit 3 with untouched input, consented file-relative shift with
convention preserved, payload intact via punk::zip members + crc-verified
extraction, icon replaced (extract-ico == punkshell.ico), idempotent re-stamp
byte-identical, make.tcl tool info punkres provenance records. Full punkexe
suite 83 tests 0 failed (no collateral).
Goal detail: Notes findings (codepage noise, root-vendorlib twapi fragility,
nested tclsfe payload, metakit move-safety -> G-101 pointer updated) +
Progress increment 1 with the two remaining acceptance items (non-windows-host
e2e, punkbin publication route) and one acceptance-wording flag for the user
(metakit 'kit' shape vs 'zip overlay' clause). punkshell 0.30.1 + CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Upstream commit 09d5ec5514bb0dbd31a38ee772e50b8d981f0219 (clean at copy time)
from the sibling checkout c:/repo/jn/zig/punkres (gitea remote recorded in
PROVENANCE.md). Vendored: build.zig, build.zig.zon, LICENSE (BSD-2-Clause,
first-party), README.md, src/ - all test fixtures synthesized in memory, no
binaries. PROVENANCE.md records origin, vendored state, re-vendor procedure
and G-063-style licence records; src/tools/AGENTS.md indexes the tree and
extends the per-tree verification note (punkres 31/31 as vendored).
Verified from the vendored location with the pinned
bin/tools/zig-x86_64-windows-0.16.0 toolchain: zig build test 14/14 steps,
31/31 tests. make.tcl tool step discovers punkres with ZERO make.tcl edits
(G-126 convention-based discovery): test gate passed, ReleaseSafe build
installed bin/punkres.exe (1073152 bytes).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
goals_xref score G-128 re-run at activation; two relationships recorded as
Notes: G-105 (host-native punkres build for the e2e non-windows clause;
cross-target builds + naming live there) and G-101 (the 'kit' shape is the
sdx/metakit container - post-hoc stamping of it rides the opaque-overlay
taxonomy, move-safety to be measured). goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full on 2026-07-29 (evidence in the detail file's
Progress section): windows-host bakes embed the default punkshell.ico
into all 10 buildable win32 kits across zip (x64 + ix86), sdx-metakit
and stamped-concat assembly, verified by twapi resource inspection
byte-matching the source ico; override round-trip proven and reverted;
boots for zip, metakit and concat images from scratch copies; linux
cross-target kit gets its sidecar with NOT APPLICABLE; the two
incapable-host conditions produce their distinct notices in REAL bakes
(mingw tclsh86: twapi not loadable; WSL linux cross-bake: cross-host
with the G-128 remedy named - and the cross-baked kit boots on windows,
the recorded known shortcoming live); idempotence converges; runtime
store originals untouched; vendored-twapi no-toolchain arm proven under
tclsh9.0.5-punk.
Index entry moves to GOALS-archive.md (ID position); the detail-file
move to goals/archive/ follows as its own pure-rename commit. Reference
sweep: G-023, G-028, G-127 and G-128 notes gain achieved/archive markers
plus what each consumes from the delivered mechanism (G-128: the seam
now exists - kit_icon_process entry point, sidecar record, cross-host
notice naming it as remedy; G-028: the stub-first ordering concentrates
the locked-target exposure at deploy, punk9_beta observed). AGENTS.md
owning-doc pointers land alongside: src/vfs (override convention),
src/runtime (default-icon role + derivation sidecar), src/assets/logo
(propagation honesty: G-057 consumes the src/runtime copy - syncing the
four build-consumed copies after artwork changes stays deliberate, with
assetorigin stale-detection as the drift signal), and an ARCHITECTURE.md
build-section bullet (architecture_lint clean).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Every kit a bake builds now gets a <kitname>.resources.toml sidecar
(build folder + deployed beside bin/<kit>) recording the build-time icon
choice: schema-1 flat TOML in the G-135 tolerant family - kit, target,
kit_type, icon_origin default|override, icon_source (repo-relative),
icon_hash, provenance source+hash lifted from the icon's assetorigin
sidecar (the chain reaches the SVG master), embedding, embedding_status
embedded|not-applicable|unavailable|failed, embedding_reason. Byte-stable
(no timestamps, write-only-if-changed); named "resources" so the parked
RT_VERSION follow-on extends the same file. Format doc: bin/AGENTS.md.
win32-target kits get the icon embedded as RT_ICON/RT_GROUP_ICON via the
twapi resource-update APIs - the tcl-sfe sfe-0.2.tm mechanism (Ashok P.
Nadkarni) generalized: enumerate all existing icon/group entries via
extract_resources, delete ALL, write ids 1..N plus one group under the
first pre-existing group's name+lang (fallback 1/1033) in a single
update transaction - idempotent by construction. Ordering is stub-first:
a PER-KIT copy of the extraction phase's payload-free raw runtime prefix
is stamped BEFORE payload attach, so the resource rewrite can never
corrupt an overlay; all three assemblers (zipfs mkimg, zipcat/concat,
sdx wrap) consume the stamped copy; runtime store originals untouched.
::punkboot::kit_icon_process is the single internal entry point with
mechanism selection inside (a G-128 portable stamper becomes a
substitution). Skip taxonomy: non-PE target / runtimeless .kit =
NOT APPLICABLE; cookfs, missing icon, missing raw prefix, cross-host
(non-windows process family), twapi-unloadable = UNAVAILABLE with
distinct named reasons; embed errors = recapped BUILD-WARNING + status
failed. Sidecar written in every case. Default icon joins the kit's
punkcheck source set (icon changes rebuild kits); sha256 self-contained
(bootsupport has sha1/md5 only), memoized per run.
Verified (evidence in the goal detail file Progress): full bake embeds
all 10 buildable win32 kits (zip x64+ix86, sdx metakit trio) with
resource inspection byte-matching the source ico (punk91, punk86,
punk91ix86 inspected; group name SFE preserved); scratch-copy boots for
zip, metakit and a stamped concat image (androwish exe-path mount);
override round-trip via punk9wintk903.vfs (solid ico embedded +
recorded, then reverted); linux cross-target punkshell902 sidecar with
not-applicable; mingw tclsh86 bake takes the concat path with the
distinct twapi-unloadable notice; vendored twapi 5.0b1 arm proven under
tclsh9.0.5-punk; double-restamp converges. punk9_beta embedded+built
but deploy still blocked by the known bin file lock (stamped product
waits in src/_build).
make.tcl workflow text gains the icon step + sidecar output; punkshell
0.29.0 -> 0.30.0 (minor: kits now wear the punkshell icon; new shipped
sidecar) with CHANGELOG entry. G-057 detail file: ordering + override +
sidecar + seam decisions recorded with tcl-sfe attribution; cross-host
known-shortcoming + G-128 remedy recorded per acceptance.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-directed proposed->active flip. Activation freshness survey
(goals_xref score G-057) found no relationships beyond those already
recorded in the detail file (G-128 and G-127 linked bidirectionally;
G-123 referenced with the optional back-pointer absent; higher-scoring
unlinked pairs are lexical coincidence). goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-approved resolution of the open call recorded at G-135 achievement:
src/vfs/_vfscommon.vfs/punkshell.ico gains its assetorigin sidecar
(schema 1, hash equals source_hash - byte-identical derived copy of
src/assets/logo/punk-mark.ico, source recorded ../../-relative). The
sidecar is root-level user-curated payload beside the icon itself
(vfscommonupdate regenerates the modules/lib subtrees, not these), and
ships inside every kit that merges the common payload from that kit's
next bake; inside a kit the recorded source is absent, so a checker
truthfully reports source-absent there while still hash-confirming the
icon bytes - in this tree it verifies (assetorigin_check: 9 records, 9
verified). The per-kit mkzipfix.vfs / punk8_statictwapi.vfs copies stay
unrecorded (no decision requested; unrecorded is silent and supported).
src/assets/logo/AGENTS.md ownership bullet and the G-057 handoff note
updated to record the made call. No bake run - deployed kits pick the
sidecar up when next baked.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Acceptance verified in full (evidence in the detail file's new Progress
section): format documented with schema key in src/assets/logo/AGENTS.md;
tolerant reader; six-state checker proven on constructed fixtures under
tclsh 8.6.11, Tcl 9.0.3 and the punk91 kit runtime; generator with no
Windows-only component regenerating all four .icos plus the web rasters
byte-identically before make-ico.ps1 was removed; sidecars exist and
verify for every generated artifact under the four asset directories
(live tree: 8 records, 8 verified).
Index entry moves to GOALS-archive.md; the detail file move to
goals/archive/ follows as its own pure-rename commit (root AGENTS.md
"Doc Restructures": moves separate from edits). Reference sweep:
G-057 and G-136 Related lines gain achieved/archive markers plus
pointers to the concrete deliverables they consume (G-057: record
format, checker, the verified src/runtime/punkshell.ico derived-copy
sidecar, and the still-open kit-shipping user call; G-136: the
committed project-default icon.ico + sidecar pair its injection copies
verbatim). src/assets/logo/AGENTS.md G-135 mentions gain archive paths.
Notes record the implementation-time resolutions: self-contained
flat-toml subset reader + embedded sha256 (no tomlish, no tcllib);
src/runtime/punkshell.ico sidecar written (passive file, nothing
ships); _vfscommon.vfs / mkzipfix.vfs / punk8_statictwapi.vfs copies
stay unrecorded pending the user call on shipping sidecars inside kits.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
scriptlib/developer/assetorigin_check.tcl, sibling to goals_lint and
architecture_lint: plain Tcl, no external binaries, no rasterizer -
embedded sha256 (NIST-vector validated) plus a tolerant self-contained
flat-TOML subset reader (comments, basic and literal strings, bare
scalars; unknown keys skipped; root table ends at the first table
header; duplicate keys last-wins), resolving the open toml/hash
dependency posture from the pre-activation review in favour of
self-containment.
States evaluated in table order, first match wins: unrecorded,
artifact-absent, replaced, source-absent, stale, verified. Unrecognised
schema or a missing/unusable artifact hash means the record is ignored
(unrecorded), never an error; unrecognised hash-algorithm prefixes are
treated as not recorded, so a source claim without a usable hash is a
presence check only.
check mode defaults to src/ (minus buildsuites/), scriptlib/ and goals/
- 2.2s wall vs 116s for a whole-tree walk dominated by _build trees,
bin/tools zig installs and TEMP_REFERENCE (those walk only when named
explicitly; .git and _build always skipped). goals_lint-style exit: 0
clean, 1 with a line per finding; advisory - nothing gates a build on
it. status mode classifies named assets (a sidecar path names its
paired asset); selftest builds 13 fixtures demonstrating all six states,
the rule-3 precedence (replaced wins over missing source) and every
tolerance rule - 16/16 pass under mingw tclsh 8.6.11, native Tcl 9.0.3
and the punk91 kit runtime. Live tree: 8 records, 8 verified.
Root AGENTS.md scriptlib/developer enumeration gains the new tool.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make-ico.tcl (any tclsh 8.6+, rsvg-convert on PATH) replaces make-ico.ps1
in place: pure-Tcl PNG decode (core zlib inflate + row unfilter) and
DIB/ICONDIR assembly take over from System.Drawing, with an embedded
sha256 (NIST-vector validated, cross-checked against Get-FileHash).
Byte-identity proven before the ps1 removal: 'all -check' regenerates all
seven recorded artifacts (punk-mark.ico, punk-mark-solid.ico,
project-default/icon.ico on the DIB+PNG256 profile; favicon.ico all-PNG;
apple-touch/192/512 rasters) byte-identical to the committed files under
both mingw tclsh 8.6.11 and native Tcl 9.0.3.
Every artifact now carries its <name>.assetorigin.toml sidecar (schema 1:
artifact sha256, source + source hash, role, generator + invocation
options), (re)written by every generator subcommand so regeneration
cannot leave a stale record. The 'all' manifest embeds the invocation
profiles; 'all -check' is the no-write drift probe (exit 1 on any
difference). src/runtime/punkshell.ico gains a derived-copy sidecar (hash
equals source_hash, source ../assets/logo/punk-mark.ico); the three vfs
copies stay unrecorded pending the user call on shipping sidecars inside
baked kits.
src/assets/logo/AGENTS.md: assetorigin schema 1 format documentation
(canonical), Tcl-generator work guidance, drift-probe verification line.
favicon source recorded as web/icon.svg (renders byte-identical to
punk-mark.svg at 16/32/48; the same-directory primary web icon chosen).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-directed proposed->active flip. Activation freshness survey
(goals_xref score G-135) found no relationships beyond those already
recorded in the detail file (G-136, G-057, G-128, G-133 all referenced;
higher-scoring unlinked pairs are lexical coincidence). goals_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Promotion gate run from a clean tree (both VCS committed at punkshell
0.29.0). Five stamped-version promotions from the deployed modules
tree: punk::args::moduledoc::punkexe 0.1.0 -> 0.1.1 (the G-033
packagemode leader with the proj: contract - kits baked from here on
carry the live launch documentation), plus four bumps pending from
earlier change-sets: argparsingtest 1.2.0 -> 1.3.0, oolib 0.1.3 ->
0.1.4, punk::zip 0.2.0 -> 0.3.0 (punkzip extraction accelerator),
punkcheck 0.6.0 -> 0.6.1 (installtrack self-heal). The
templates-0.2.0.tm modpod refreshed by the same replace (zip .tm,
rides binary-glob; existing artifact updated, no new binaries).
Kits pick these up at their next 'make.tcl bake'.
Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Activation and achievement same day at user direction ('activate and
start on it'). Activation freshness survey (goals_xref score G-033)
recorded in the detail file: G-043's one-directional reference is the
only unlinked real relationship; G-123/G-127/G-131 overlap by
punk_main.tcl/bin co-location only.
Detail file gains the Progress record (option (a) inline-walk
decision, verification evidence on the rebaked punk91 kit, the
moduledoc-0.1.1 live-help note and the pending vfscommonupdate
promotion) and moves content-identical to goals/archive/; index entry
moves GOALS.md -> GOALS-archive.md.
Reference sweep: G-016/G-047 relationship notes point at the archive
and the ::punkboot::proj_root_find delivery; G-032's Approach now
says the packagemode leader text is LIVE and its remaining lane is
rendering/parse wiring; G-089's Related note records that the visitor
root walk it rides is live, remains defined post-boot, and that the
boot-interface packagemode hint it needs is still absent; G-031 gains
the fork-drift datapoint (proj: landed in punk_main.tcl only,
project_main.tcl still lacks src mode and proj:); G-018/G-035/G-043
mentions gain achieved/archive markers.
goals_lint clean (85 active, 51 archived), architecture_lint clean.
Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk_main.tcl: an optional proj: prefix on the package-mode string
(e.g 'proj:internal-src') rebinds the dev/src path blocks to the punk
project containing the current directory instead of the executable's
own project. Root discovery is ::punkboot::proj_root_find, a lean
boot mirror of punk::repo::find_project/is_project_root in Tcl
builtins only (git/fossil control markers via 'file exists', unwise-
path exclusion, ./src plus src/modules|src/vfs|src/scriptapps|
punkproject.toml candidate check; .git accepted as file OR dir for
worktree checkouts - recorded divergence). The proc stays defined
post-boot like the G-129 mount procs. The prefix sits outside the
ordered dash-list, whose block order remains the same-version
tie-break dial; an invalid mode remainder is not consumed (whole arg
falls through as subcommand/script as today); bare 'proj:' reads as
internal and warns. Discovery outcome is always reported on stderr
(detected root + effective precedence - never a silent rebind), a
failed walk-up warns and leaves dev/src unbound (no exe-relative
fallback rebind), and proj: without a dev/src block warns it has no
effect. Under proj:, dev resolves <root>/modules{,_tclN} and
<root>/lib{,_tclN} only; src feeds the discovered root into the
existing src-mode machinery unchanged (tm paths, auto_path, package
prefer latest, inline #modpod scanner). Exe-relative src/dev launches
are untouched.
punk::args::moduledoc::punkexe 0.1.1: the packagemode help text
drafted in the goal file is now live as the packagemode leader of
(script)::punkexe (@leaders max 2), with proj: wording in the @cmd
overview; rendering/parse wiring remains G-032.
Verified on a rebaked punk91 kit, standalone copy outside any source
tree: proj:internal-src from tomlish (fossil root, builds no
executable) loads tomlish 999999.0a1.0 from its src/modules with
kit-first ties; proj:src flips the ordering; from punkshell the
visited-root modpod scan registers 6 modpods; no-project and
no-root-using-block warnings fire and proceed; bin/punk91 src
unchanged.
Docs: bin/AGENTS.md launch-package-modes proj: contract,
src/vfs/AGENTS.md punk_main contract line, ARCHITECTURE.md entry
point. punkshell 0.29.0 (minor - new launch invocation) + CHANGELOG.
Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Pre-activation review outcome (user-approved wording): G-135's record
shape pivots from one assetorigin.toml per directory to a per-asset
sidecar, <asset-filename>.assetorigin.toml beside the asset it
describes.
G-135 contract: Scope (both tiers, mirror-identical) names per-asset
*.assetorigin.toml sidecars. Acceptance rebuilt - records are bound by
the sidecar's own filename (suffix stripped, same directory; files
ending in the suffix are records, never assets; reader tolerance kept);
the checker's state model is repaired to six states evaluated in table
order with first match winning (artifact-absent added for records whose
paired asset is gone; verified now requires every hash the sidecar
records to match, so a hash-only sidecar verifies on the artifact hash
alone; fixtures must distinguish stale / replaced / artifact-absent);
the generator clause requires byte-identity per the invocation profile
that produced each .ico and that the generator (re)writes each produced
artifact's sidecar, so regeneration cannot leave a stale record; the
final clause requires sidecars to exist and verify for every generated
artifact under the four asset directories.
G-135 body: Approach carries the pairing rationale (no path key, file-
pair lifecycle, survives wholesale and single-asset copies, composes
under merge_over same-path replacement) and the hash-required minimum;
the six-row state table gains the evaluation-order and unhashed-claims
notes. Alternatives inverted: the per-directory [[asset]] record is now
the rejected shape (shared-state writers - the punkcheck G-094/G-095
lesson; file-level clobber at a .vfs root under overlay merges;
invisible dangling entries; single-asset copies lose their record), and
a fauxlink-carried record is recorded as considered-and-rejected (the
filename would encode a mutable fact; overlay pairing would need a
nominal-keyed composition invariant in every composer), preserving the
nominal-keyed idea as fauxlink hardening independent of this goal (71
fauxlinks in tree, zero same-directory nominal collisions, surveyed
2026-07-28). Notes add the override-without-sidecar kit behaviour
(travelled common sidecar truthfully reads replaced), the eased checker
parsing posture, and the open pre-activation items (which of the four
build-consumed punkshell.ico copies get sidecars; whether a
_vfscommon.vfs sidecar shipping inside every baked kit is the intent).
G-136: acceptance names icon.ico.assetorigin.toml and the per-asset
dependency; Approach/Notes reworded to match. G-057: one Notes sentence
disambiguates its per-kit icon sidecar from G-135's record sidecars.
goals_lint clean (index/detail mirrors exact, archived-goal references
markered); goals_xref score G-135 re-run - G-136 and G-057 linked.
G-135 stays proposed; activation is the user's flip.
Claude-Session: https://claude.ai/code/session_014wNGMsdNFFrU1duADeirgm
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The Origin section now names the upstream by its remote and expects the
working checkout at ../zig/punkzip relative to the punkshell repo root,
stated as a layout convention with its fallback spelled out (clone the
remote there; the pinned Vendored state commit identifies the exact
upstream state in any clone). The re-vendor procedure now runs entirely
from the punkshell repo root (git -C ../zig/punkzip checks, relative cp
sources), making it copy-pasteable on any machine reproducing the
sibling layout and independent of the punkshell checkout's own
directory name (survives the G-022 rename).
PROVENANCE.md was the only operational document carrying the
machine-local path - the c:/repo/jn absolute references in goals,
archives and CHANGELOG are historical narrative and stay as-is. G-135
names this file's prose as the src/tools vendored-tree convention, so
the relative form is set while there is one instance to copy.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The catch-up checkin aborted on CRLF in files outside crlf-glob. Five real
offenders, in two classes needing opposite treatment:
- src/buildsuites/suite_tcl86/patches/* (three files) is vendored sdx source by
Matt Newman and Jean-Claude Wippler plus the patch derived from it. Upstream
CRLF, and the patch must stay byte-exact to apply. Added to crlf-glob, which
is what .fossil-settings/AGENTS.md prescribes for a payload tree that trips
the prompt - explicitly in preference to reaching for --no-warnings.
- src/modules/oolib-buildversion.txt and src/buildsuites/suite_tcl86/src/main.zig
are authored punkshell files (4 lines each, fully CRLF) that the root AGENTS.md
LF preference governs. Converted rather than globbed; globbing src/modules
would suppress the warning across authored territory.
punkzip's hamlet.txt was a false positive in the first scan - already covered by
the crlf-glob entry for its fixtures directory, where it is deliberately CRLF
byte-exact test data.
Converted in git first so the fossil checkin records identical content; a
content fix applied only fossil-side would desynchronise the two mirrors in the
middle of a catch-up.
Note oolib-buildversion.txt is build-generated, so a future regeneration may
reintroduce CRLF there.
Claude-Session: https://claude.ai/code/session_01YNjnq6oDzecknLg7AuWZgU
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
The module hard-required opt, cmdline and tepam at load time, so on a punkshell build
without tcllib 'package require argparsingtest' died outright with "can't find package
opt". A harness whose whole job is comparing parser libraries is useless precisely on the
runtime you wanted to measure, and the module already had the right pattern for this:
argp, parse_args and argparse degrade to a not_loaded row rather than taking the module
down with them. The three tcllib parsers were the odd ones out. Reproduced before the
change with punk module paths only and an emptied auto_path, which is where tcllib's
pkgIndex-based packages come from.
Every parser this module compares is now optional. Their roster entries become
{optional opt}, {optional cmdline} and {optional tepam}, so discover_parsers reports
not_loaded when the package is absent and nothing in the harness calls them. punk::args
and Tcl 8.6- remain hard requires - the harness itself is built on those.
The guard differs by package because the dependency does:
cmdline is only ever called INSIDE proc bodies, so the catch-guarded require at the top
is the whole story - the wrapper procs stay defined and are simply never invoked.
opt and tepam are used at DEFINITION time: tcl::OptProc and tepam::procedure are the
commands that create the wrapper procs. Their seven definition sites (four opt, across
opts/tkstyle/tclstyle/sandwich; three tepam) are each additionally guarded, so with the
package absent the proc does not exist at all.
Those sites test 'package present' rather than wrapping the definition in a bare catch.
Both tolerate absence, but a presence test still lets a genuine error in a spec raise
loudly on a runtime that does have the package, where a catch would swallow it. The
pre-existing argp registration site keeps its original catch idiom - working code, not
part of this change.
Pinned by module_loads_without_optional_parser_packages: a child interp with an emptied
auto_path that asserts the module loads, that each absent package's parser reports
not_loaded, and that the opt and tepam wrapper procs genuinely do not exist. Where a
runtime supplies one of the three as a .tm on a module path the test degrades to
asserting the module still loads, which is the main claim anyway.
Tests that name parsers explicitly (first_call_library_backed, first_call_positional_styles,
sandwich_strictness) now filter through a loaded_parsers helper, and the tclstyle
cmdline_typed status assertion derives its expectation from package presence: those
parsers can now legitimately be missing.
Verification: 26/26 pass under the 32-bit luck-test2 runtime with no skips, 24 pass +
2 skip under native Tcl 9.0.3. With opt and tepam hidden, the built 1.3.0 module loads,
reports both as not_loaded, and compare lists them in its "not loaded:" footer instead of
the whole module failing to load.
Claude-Session: https://claude.ai/code/session_01Q82VuBXzgeKsAwMYHrbpP1
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Non-contract Notes addition (user-directed). G-133 (achieved 2026-07-27) landed the
structural arch scan this goal's Acceptance still asks for: a recapped BUILD-WARNING
naming file, found architecture and kit target; no warning for multi-arch
platform-subdir packages or recognised vendor spellings; and the scan running for
cross-target kits. That covers the clause in full.
The clause is deliberately left in place rather than trimmed - trimming an Acceptance is
a contract edit - so the note says how to read it: a regression pin on behaviour that
already exists, not work to do. It also states the goal's genuine remainder so whoever
activates it is not misled about the size: the bin/kits/<platform>/ output split, the
per-target payload declaration, and keeping G-133's smoke probe pointed at wherever the
relocated artifact lands.
Goal, Acceptance and Scope are unchanged.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Two proposed goals from the src/assets/logo work, split rather than combined:
"the master-to-derived chain is verifiable anywhere" and "generated projects
arrive with an icon" are separate outcomes with separate acceptance, and the
second merely consumes the first.
G-135 - asset provenance records. Nothing currently states that
src/runtime/punkshell.ico came from punk-mark.svg, so one failure is
undetectable: edit the SVG, forget to regenerate, and the committed .ico
silently stops depicting the master. An optional directory-scoped
assetorigin.toml records the derivation; a plain-Tcl checker classifies each
asset as unrecorded / verified / source-absent / replaced / stale, advisory
only. Absence of a record is the DEFAULT and stays silent - a record is an
opt-in claim, and every field but path is optional, so "I know this file, I
don't know where it came from" is expressible.
The same goal retires the Windows tie in make-ico.ps1. The dependency is one
line - System.Drawing, decoding PNG to raw BGRA - since pwsh and rsvg-convert
are both cross-platform and Tcl core ships zlib.
G-136 - generated projects seeded from src/assets/logo/project-default/ at
generation time, as a sibling to bootsupport_inject with punkcheck install
records, rather than storing artwork in layout trees. Layout storage would mean
three copies with no master (project-0.1, basic, and the punkcheck-managed
modpod-templates copy), reversing G-087's thin-layout achievement. Because
G-135's record is directory-scoped with relative paths it copies verbatim and
reads `verified` at the destination.
Scope for G-135 separates the two tools rather than bundling them: the generator
is replaced in place under src/assets/logo/ (it operates on the files beside it
and is already documented there), while the checker is a lint in the shape of
goals_lint and architecture_lint and belongs in scriptlib/developer/ - with the
home explicitly revisited if it becomes a bake step, since scriptlib/ is
user-only and make.tcl must not depend on it. That deferral follows G-057's
existing "helper proc location decided in the work" pattern.
Both goals record the workflow questions deliberately kept OUT of their
acceptance: when the checker runs (bake step vs subcommand), and which layouts
declare an icon slot.
G-057 gains a Related pointer to G-135 per the dependency-direction convention -
its per-kit sidecar is specified to carry "source .ico identity and provenance",
which these records are the natural source for.
goals_lint clean (86 active-index goals, 50 archived); the G-133 reference
carries its archive marker in Notes per the Archive rules.
Claude-Session: https://claude.ai/code/session_01YNjnq6oDzecknLg7AuWZgU
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
The four build-consumed copies are renamed and their artwork replaced with
src/assets/logo/punk-mark.ico (all four byte-identical to the master):
src/runtime/punk1.ico -> src/runtime/punkshell.ico
src/vfs/_vfscommon.vfs/punk1.ico -> .../punkshell.ico
src/vfs/mkzipfix.vfs/punk1.ico -> .../punkshell.ico
src/vfs/punk8_statictwapi.vfs/punk1.ico -> .../punkshell.ico
Recorded as delete+add rather than renames: the content is entirely different,
so git's similarity detection finds no link and --follow will not trace through.
The pre-2026-07 artwork keeps its own lineage under src/assets/logo/legacy/,
now the only place the punk1 name survives.
No code referenced the old name - every mention was documentation or goal prose,
checked before renaming.
G-057's contract lines are updated for the new path (Scope in both tiers, plus
Goal and Acceptance): pure path substitution, no semantics changed. Its Context
gains a dated note recording the rename and artwork swap, and its _vfscommon.vfs
override-detection wrinkle now names punkshell.ico. goals_lint clean.
Adds src/assets/logo/project-default/, a frozen monochrome placeholder - a blank
screen wearing the crest - held as the single copy for seeding generated
projects. Unbranded so it reads "replace me" rather than as a product identity.
Bezel and crest are ONE union path (drawn as two shapes the bezel's top edge
cuts a visible line across the mohawk) and the screen is filled rather than
outlined (a solid mass survives 16px where nested thin strokes merge). It shares
only the crest with punk-mark.svg and must not be re-derived from it: tracking
the real mark would churn every generated project on every logo tweak.
Also corrects a defect introduced in 91fa500e. The Ownership bullet in
src/assets/logo/AGENTS.md said "do not repoint build consumers at this directory
on your own initiative" and then, in the next sentence, instructed re-copying
them by hand after regeneration - so whichever half an agent read first would
win. It now states the dated fact and names G-057 as the owner of future
propagation. Distribution machinery does not belong in an AGENTS instruction,
and drift wants a check rather than a standing manual obligation.
Stale punk1.ico copies were also swept from the untracked build trees
(src/_build x12, bin/test, bin/test2, scratch, testsdx) so the next bake cannot
merge both names into a kit payload.
Claude-Session: https://claude.ai/code/session_01YNjnq6oDzecknLg7AuWZgU
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Replaces the busy pixel-art punk1 artwork - unreadable below ~32px - with a flat
two-colour mark: a mohawked terminal plate enclosing Tcl's [ ] command
substitution, Emerald #0FA36B on ink #03120C. Drawn on a 64x64 grid to hold at
16px and verified by rendering at true pixel size on both light and dark plates,
rather than judging it large and hoping.
src/assets/logo/ is the icon MASTER, distinct from the build-consumed copies at
src/runtime/punk1.ico and src/vfs/_vfscommon.vfs/punk1.ico. Those are
deliberately untouched and remain a user-directed swap.
punk-mark.svg/.ico outline plate (primary)
alternative/punk-mark-solid.* solid plate
web/ favicon set
legacy/ retired punk1 artwork, moved from repo root
make-ico.ps1 keeps the .ico reproducible: rsvg-convert for true-alpha
rasterizing (never browser screenshots - they bake in a background and lose the
alpha the icon depends on), then a hand-assembled ICONDIR. PE icons carry
16/24/32/48/64/128 as uncompressed BGRA DIBs plus a PNG-compressed 256, keeping
that entry ~5KB instead of ~265KB - each entry becomes a separate RT_ICON in
every embedding kit. Regeneration is deterministic, byte-identical across runs.
The web set inverts those tradeoffs. favicon.ico is 16/32/48 all-PNG (2.5KB,
fetched on every cold page load) and is web-only: all-PNG is precisely what GDI+
and tklib's ico package cannot read. web/icon.svg carries a prefers-color-scheme
block serving the outline plate to light tab bars and the solid plate to dark -
something an .ico structurally cannot do - verified by rendering under forced
dark. The apple-touch and PWA rasters are deliberately opaque, since iOS ignores
transparency and composites against black.
Two decoder limits are recorded in the new AGENTS.md as properties of the
readers, not defects in the files: legacy GDI+ silently returns the 128px frame
when asked for 256 (WIC, which Explorer and the taskbar use, reads all seven),
and tklib's ico package parses DIB entries only.
Root and src AGENTS.md gain Child DOX Index entries. Both converted to LF per
the root line-ending policy, which explicitly declines diff-minimisation as a
reason to preserve CRLF.
No punkproject.toml bump: these assets are a non-shipped surface until a build
consumer is repointed. Fossil still tracks the three legacy files at their old
root paths and needs the rename at the next catch-up checkin.
Claude-Session: https://claude.ai/code/session_01YNjnq6oDzecknLg7AuWZgU
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Clears the 5 informational goals_lint warnings, all on this file: G-096, G-098,
G-099, G-100 and G-103 were referenced with no achieved/archive marker anywhere.
The check reads a 3-line window around each G-<n> mention for
achieved|archive|landed and ORs across every mention in the file, so ONE marked
mention clears an id. That matters here: G-103's only mentions are in Scope
(index-canonical) and Acceptance (detail-canonical), both proposal-first. Neither
is touched - the marker goes in Notes per the goals/AGENTS.md Archive rules,
carrying the archive path and stating what G-103 contributes (the artifact-
metadata contract those two lines name: a published runtime's record carries its
target, which for this goal must name the 32-bit platform).
G-096/G-098/G-099/G-100 are marked in place in Context. That mention is pure
history - the phrasing was already factual rather than pending-tense - so a
compact "all achieved and archived" is proportionate to the rules' guidance
rather than four inline archive paths.
Context paragraph reflowed to the file's ~90-char wrap (the marker insertion had
pushed one line to ~118). Body lines now top out at 97, a pre-existing line; the
1180-char maximum is the Acceptance line, single-line by header grammar and
unchanged.
goals_lint clean (84 active-index goals, 50 archived).
Claude-Session: https://claude.ai/code/session_01Y1diJnhjUxKgEG6EwYAzxj
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
Every acceptance clause is met: vendored source green under the pinned
zig 0.16 toolchain via the make.tcl tool step (zig optional), upstream
extract-to-directory + pinned porcelain listing, punk::zip accelerator
with the parity suite (identical names/bytes/mtimes both engines over
the G-124 shapes and the file-relative piperepl kit; pure path proven
when absent), recorded benchmark (crossover ~15-20 members, material
from ~50, x2.3-2.6 native / x3.8-4.9 kit-hosted), and PROVENANCE.md
origin/re-vendor/licence records.
Index entry moved to GOALS-archive.md; detail Status flipped (the file
moves to goals/archive/ in the adjacent pure-rename commit). Reference
sweep: G-101's pending-tense accelerator mention rewritten as achieved
with the archive path; G-128's Depends-on gains the archive pointer
plus the now-existing pattern surface and the zig-0.16 traps its port
should read first.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Bootsupport promotion of the G-126 accelerator module (superseded 0.2.0
pruned by the punkcheck-managed step). make.tcl's zipfs-less bake
extraction path now carries the accelerator-capable punk::zip.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The final G-126 acceptance clauses:
- punk::zip::accelerator (auto|none|<path>): auto probes
env(PUNKZIP_EXE) then a punkzip beside [info nameofexecutable];
resolution cached until reconfigured
- unzip hands whole-archive member WRITING to the accelerator only when
the call is one it serves identically (globs {*}, no excludes,
default -overwrite/-mtime/-verify, ascii member names) and re-stamps
mtimes with punk::zip's local-time convention afterwards, so the two
engines produce identical trees; preflight refusals, member selection
and the returned names always come from punk::zip's own reader (the
G-124 floor, unchanged); accelerator failure falls back to pure Tcl
silently; last_unzip_engine/last_accelerator_note expose the per-call
decision
- parity suite zipaccel.test (9 tests): identical names, bytes and
mtimes through both engines over the G-124 shapes and whole-kit
extraction of the file-relative tclsh90b4_piperepl.exe (841 members);
listings engine-independent; punkzip porcelain agrees with punk::zip
member dicts on every shared field (mtime excluded by design - UTC vs
local convention); pure path proven when the binary is absent;
selective calls proven to run pure. Implicit directories (kits store
no dir entries) are excluded from mtime comparison - neither engine
stamps them
- recorded benchmark (in the goal detail): accelerator fixed cost
~9-13ms, crossover ~15-20 members, material (>= x1.7) from ~50;
x2.3-2.6 at kit scale under a native tclsh and x3.8-4.9 kit-hosted
(punk91.exe 21.9s -> 5.7s) - the bake-from-kit case the goal
motivated
- full runtests at recorded baseline under tclsh9.0.5-punk: 1186/1211,
1 failed = the pre-existing exec-14.3 baseline
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Thin-layout sync (part of the bootsupport run): the project-layout
make.tcl copies (vendor/punk/basic, vendor/punk/project-0.1, and the
punk::mix::templates modpod source tree) pick up the G-126 'tool'
subcommand from d76a7907 via the punkcheck-managed sync step. No hand
edits.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Field failure (2026-07-27, second dev machine): 'make.tcl bake
punk9_beta' died in the vfslibs phase with
eventcollection ... key '$eventid' already exists in collection
because that machine's src/vfs/.punkcheck predates punkcheck 0.3.2.
The 0.3.2 note fixed the WRITER (a braced template wrote the literal
strings '$eventid' etc into event headers) but files written before it
keep the damage, and the modern installtrack constructor - which
reloads persisted events into a collection keyed by -id - collided on
the duplicate literals and aborted the whole bake.
- punkcheck 0.6.1: the constructor reload now self-heals instead of
aborting: an EVENT record with a missing or duplicate -id is
reconstructed under a synthesized unique id ('damaged-id-...') with
a stderr warning naming the file and the offending id. Synthesized
ids match no INSTALL record's -eventid reference, so healed events
age out through normal -keep_events pruning. Reload also tolerates
missing -source/-targets keys.
- oolib 0.1.4: the collection duplicate-key error no longer misnames
the object as 'col_processors' (stray copy-paste in the generic
class).
- regression test installtrack_damaged_event_history_selfheal seeds a
real two-event file, rewrites both -id values to the braced literal
{$eventid} (as the damaged files carry it - the record loader
evaluates records, so only a braced literal survives as the string),
and asserts the reload succeeds with both events kept under distinct
keys (one healed). Suite: 30/30.
- before/after proof against the released artifacts: punkcheck 0.6.0
(exact-pinned) reproduces the field abort on the crafted file;
0.6.1 heals it. Bootsupport promoted to punkcheck-0.6.1 + oolib-0.1.4
(superseded copies pruned), so make.tcl bakes get the fix.
Remedy already applied on the affected machine (file deletion); with
this fix, remaining old .punkcheck files anywhere self-heal with a
warning instead of failing builds.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
New surface for the vendored first-party build tools under src/tools:
make.tcl tool list|info|build|test ?<toolname> ...? ?-test 0|1?
- discovery is convention-based (a src/tools directory carrying
build.zig is a tool), so the G-128 tool will appear with zero
make.tcl edits; per-tool records are read tolerantly from
build.zig.zon (version, minimum_zig_version floor) and PROVENANCE.md
(upstream, vendored commit)
- list/info report installed-binary state (current|stale|absent vs
bin/<name><exe-suffix>) and the resolved toolchain
- toolchain resolution: PUNK_ZIG=<path> overrides; otherwise
bin/tools/zig* is scanned and the LOWEST release satisfying the floor
wins - deterministic as newer toolchains get unpacked beside the
pinned one; dev builds count only when their base version exceeds
the floor
- build runs the tree's own 'zig build test' as an EXIT-CODE gate
(expected stderr warnings do not fail it), then builds ReleaseSafe
and installs to bin/; nothing installs when the gate or build fails;
-test 0 skips the gate; build caches are deliberately left in place
between runs for rebuild speed (git- and fossil-ignored)
- zig stays OPTIONAL: packages/bake never require the step; without a
suitable toolchain, list reports the state and build/test exit
nonzero with bin/punk-getzig.cmd guidance
- full subcommand accompaniments per src/AGENTS.md: punk::args argdoc
(SUMMARIES/HELPTEXTS/bespoke passthrough definition), SUBGROUPS
("vendored tools"), known_commands, degraded-mode dispatch, plain
help text, bootsupport-staleness exemption, workflow text (new
OUT-OF-BAND SUBSYSTEMS section also covering buildsuite), project
version 0.28.3 + CHANGELOG entry
- piped characterization (zig-independent):
src/tests/shell/testsuites/punkexe/maketcltool.test - 4/4 green
- verified live: 'tool build punkzip' gated on the vendored tree's
130/130 suite and installed bin/punkzip.exe (ReleaseSafe, v2.3.1,
1.1MB) over the stale Nov-2024 v2.1.0 binary; list state flipped
stale -> current; PUNKBOOT_PLAIN degraded dispatch and tabled help
verified
G-126 Progress updated: the acceptance's build-step clause is
satisfied. Remaining: punk::zip fast path, parity suite, benchmark.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Vendored per the goal's developer decision: build.zig, build.zig.zon,
LICENSE + LICENSE-time-dot-zig, README.md and src/ (sources and test
fixtures) from the clean upstream checkout at commit
0882f0373eb2c983142e713c814b91aa82cfcea7 (punkzip v2.3.1). Upstream
doc/ (article mirrors), reference/ (hwzip 2.4 C source) and repo-local
agent/porting notes are deliberately not vendored.
- src/tools/punkzip/PROVENANCE.md: origin, vendored commit, re-vendor
procedure (clean-upstream-only), G-063-style licence records
(public-domain hwzip lineage, MIT musl time.zig, zero dependencies)
- src/tools/AGENTS.md: new DOX child - vendored-tools boundary,
upstream-first editing policy, pinned-toolchain verification; indexed
from src/AGENTS.md
- .fossil-settings/crlf-glob: cover the vendored fixtures (hamlet.txt
is CRLF byte-exact test data the compression tests pin sizes
against; git stores it verbatim - core.autocrlf false)
- verified from the vendored location with the pinned
bin/tools/zig-x86_64-windows-0.16.0 toolchain: zig build test 25/25
steps, 130/130 tests green; build outputs (.zig-cache/, zig-out/)
were already gitignored at any depth
Goal Progress updated: the acceptance's vendoring clause (origin,
state, re-vendor procedure, licensing) is satisfied. Next: the
make.tcl tool build step.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Upstream punkzip 0882f03 fixes the long-standing dir-mtime limitation
via a deferred post-extraction stamping pass (windows direct
CreateFileW BACKUP_SEMANTICS + SetFileTime; Io best-effort elsewhere),
pinned by tests at the stored epoch including the -d route and the
build roundtrip. Notes bullet updated from proven-fixable to fixed.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
File mtimes preserved exactly (no regression old->new exe); atimes and
directory mtimes not preserved - the dir case is the long-standing zig
limitation, still present in 0.16 Io, but proven fixable via direct
CreateFileW(BACKUP_SEMANTICS, WRITE_ATTRIBUTES) + SetFileTime with a
deferred post-extraction pass. Also records the DOS-time-as-UTC vs
UT-extra-field semantics difference vs bsdtar for the parity suite.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Upstream punkzip 572d893 (v2.3.0, 130/130) turns the January build
scaffolding into a working streaming recursive zip writer per user
decision (finish rather than remove - the shipped tool should be useful
from the start). Progress records the design (per-member streaming,
sorted deterministic entries, dir members, zip64 refusal) plus the
second zig-0.16 trap found en route (OpenFileOptions.allow_directory
defaults true, breaking file-vs-dir probes). Remaining-for-acceptance
list now starts at vendoring.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com