Tree:
5e9f1c75fc
master
v0.1a
${ noResults }
314 Commits (5e9f1c75fc081d80b00aa272a660b9e82880b840)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
5e9f1c75fc |
G-128: seam selects punkres when built; characterization tests; punkshell 0.30.1
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 |
2 days ago |
|
|
6558a32e7e |
G-128 activated (user-directed): status flip + activation-freshness overlap survey
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 |
2 days ago |
|
|
88f176efb2 |
G-057: archive move (pure rename)
goals/G-057-kit-icon-embedding.md -> goals/archive/, content identical; flip edits landed in the preceding commit per root AGENTS.md "Doc Restructures" move/edit separation. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
47c9f99eff |
G-057 achieved: flip, archive record, reference sweep, owning-doc pointers
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 |
2 days ago |
|
|
5a8a62547b |
G-057: kit icon step - resource sidecar every target, twapi PE embedding
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 |
2 days ago |
|
|
b757d183e8 |
G-057 activated: kit icon sidecar + PE resource embedding
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 |
2 days ago |
|
|
af6aebda16 |
_vfscommon.vfs punkshell.ico sidecar: kit-shipping call made
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 |
2 days ago |
|
|
a1879ef4cf |
G-135: archive move (pure rename)
goals/G-135-asset-provenance-records.md -> goals/archive/, content identical; flip edits landed in the preceding commit per root AGENTS.md "Doc Restructures" move/edit separation. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
633b55faa0 |
G-135 achieved: flip, archive record, reference sweep
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 |
2 days ago |
|
|
bcf6625d7b |
G-135 activated: asset provenance records
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 |
2 days ago |
|
|
59bdb1ec49 |
G-033 achieved: flip, archive, reference sweep (proj: visitor mode live)
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
|
2 days ago |
|
|
b692979c6a |
G-135 + G-136: per-asset assetorigin sidecars replace the directory record
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 |
3 days ago |
|
|
e3d4338963 |
G-127 notes: record that its payload/target mismatch clause is already delivered by G-133
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 |
3 days ago |
|
|
164687d260 |
G-135 + G-136: asset provenance records and generated-project icon seeding
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 |
3 days ago |
|
|
7280739204 |
Project icon: punk1.ico -> punkshell.ico, artwork from the src/assets/logo master
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
|
3 days ago |
|
|
ec3e664edf |
G-130: archive markers on archived-goal mentions (goals_lint sweep)
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 |
3 days ago |
|
|
65c9dcf0b8 |
G-126 detail file -> goals/archive/ (pure rename)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
3 days ago |
|
|
5c25d15cc7 |
G-126 achieved 2026-07-27: flip + archive record + reference sweep
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 |
3 days ago |
|
|
df6642e189 |
punk::zip 0.3.0: punkzip extraction accelerator + parity suite (G-126); 0.28.4
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
|
3 days ago |
|
|
d76a7907ea |
make.tcl tool subcommand: build vendored zig tools into bin/ (G-126); 0.28.3
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
|
3 days ago |
|
|
1cdfb88693 |
G-126: vendor punkzip v2.3.1 into src/tools/punkzip/ (upstream 0882f037)
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 |
3 days ago |
|
|
24fe206b56 |
G-126 progress: directory-mtime restoration landed upstream (v2.3.1)
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 |
3 days ago |
|
|
cb16130907 |
G-126 notes: extraction timestamp behaviour measured + dir-mtime fixability proven
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 |
3 days ago |
|
|
9f4e901fbf |
G-126 progress: build subcommand finished upstream (streaming writer)
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 |
3 days ago |
|
|
01fce6b735 |
G-126 progress: upstream CLI features landed (extract -d, list -porcelain)
Upstream punkzip 7f88096 (v2.2.0, suite 128/128) delivers both upstream-side prerequisites from the goal's Approach: the extract-to-directory argument and the machine-readable listing mode with its format pinned by CLI tests. Progress records the v1 porcelain format contract for the parity-suite work; remaining-for-acceptance list trimmed accordingly. Also noted: user-committed reference/ hwzip 2.4 C source upstream (cb2a731). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
3 days ago |
|
|
eaf5be991c |
G-126 progress: upstream zig 0.16.0 port complete + base_offset tests
Upstream punkzip commits 3b87087 (0.16.0 port, floor moved, Init/Io threading, build-graph install-order fix, msys overlapped-stdout fix, v2.1.3, verified 841-member CRC extraction from the file-relative piperepl kit) and 2e49c75 (three prefixed-zip container tests pinning base_offset for both offset conventions; suite 125/125). Notes gain the overlapped-stdout trap record (applies to the G-128 tool as well); Progress section added with the remaining-for-acceptance list. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
0ad8544ee0 |
G-126 activated (user-directed): punkzip accelerator work begins
Status proposed -> active in the index with the detail-file mirror updated. Pre-activation baseline is recorded in the detail file Notes; first work item is the zig 0.16 port of the upstream checkout. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
f153a48d7e |
G-126 pre-activation baseline recorded: upstream punkzip 0.15.2 green checkpoint
Upstream c:/repo/jn/zig/punkzip commits e9b5b553 (0.15.2 migration completed, zig build test 122/122 green - bitstream wiring fixed, CLI suite compiling and pinning current output) and 78453fc0 (localtime banner restored dependency-free on stderr; zeit stays out per user decision). Context refreshed; Notes record the decisions, the stdout/stderr contract, and the known upstream gaps (base_offset untested zig-side, build subcommand scaffolding, 0.16 argsAlloc). Non-contract detail-file updates only; status stays proposed - activation flip awaits user confirmation. goals_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
9b0fe35aa0 |
G-134 drafted + G-128 amended (user-approved): archive-relative bake pin, consented file-relative stamping
Two halves of one file-relative policy decision. G-134 (new, proposed): advisory post-assembly punk::zip::archive_info probe at the G-133 seam pins make.tcl's own kit outputs archive-relative - by-construction property becomes a checked contract; mkzip -offsettype file and modpod stay available for deliberate manual creation. G-128: the straight file-relative refusal becomes default-refuse with a consent-flag preserve (central-directory offset fix-up by the shift delta, zip64/multi-disk still refused), plus Notes recording the rationale, the Authenticode sign-after-stamping rule, and the convention-conversion parking. goals_lint clean (85 active, 49 archived). Assisted-by: harness=opencode; primary-model=openrouter/moonshotai/kimi-k3; api-location=openrouter.ai |
4 days ago |
|
|
5a51cd87c4 |
G-133 sweep completion: direct Related pointers for pairs de-bridged by the archive
goals_xref report showed G-127<->G-131 (sole bridge G-133) and G-123<->G-127 (both bridges now archive-tier) as unlinked pairs with real overlap - recorded directly in G-127's Notes per the flip's shared-archived-refs rule. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
81148b8fa7 |
G-133 detail file -> goals/archive/ (pure rename)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
f5a559038e |
G-133 achieved 2026-07-27: activation + flip + archive record + reference sweep
Activation (user-directed this session) through achieved flip in one lifecycle change-set: index entry moved to GOALS-archive.md (Scope relocated verbatim; title preserved with the [achieved] status transform; Detail: line becomes the archive detail pointer - the standard flip transformations), detail file gains the activation survey Related: notes (G-114 prevention-side sibling, G-128 sibling PE surface), the advisory-as-drafted open-decision resolution, and the full Progress/verification records (live bake evidence on punkluck86/punk91ix86/punk86/punkshell902, the zint real finding, 92.6ms avg scan cost, suite results). Reference sweep pushes the archived file's actionable notes to G-024 (toml schema home), G-131 (one-vocabulary + runtime_caps), G-127 (target-addressing adoption), G-130 (subdir exemption for 32-bit growth), G-123 (publication citation), G-114 (detection-side sibling). Detail file moves to goals/archive/ in the following pure-rename commit. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
7a37e36362 |
G-133 drafted (user-approved): bake payload/target consistency checks
Candidate goal from the G-129 aftermath (user-observed 32-bit kit breakage): an advisory binary-architecture scan over the merged tree at the G-125 gate seam (platform-subdir aware, covers cross-target kits) plus a per-kit post-bake smoke-require probe through the artifact's own tclsh subcommand (plain package require - the only observer of version-preference shadowing). Overlap survey named G-024/G-131/G-127/G-028/G-130/G-123, non-overlap G-115, precedent G-125/G-129. Advisory-vs-gate for smoke failures recorded as the open decision at activation. Claude-Session: https://claude.ai/code/session_01UEgomWq6kA6c4A8GswqqGW Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
93968a5609 |
G-129 detail file -> goals/archive/ (pure rename)
Claude-Session: https://claude.ai/code/session_01UEgomWq6kA6c4A8GswqqGW Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
1fd8af5465 |
G-129 achieved 2026-07-27: flip + archive record + reference sweep
Detail file: Status flipped, Context table corrected (the LUCK backport HAS a ::zipfs ensemble - just no root subcommand), Progress + verification records added (both 32-bit kits boot and resolve from their mounts, four 64-bit kits byte-identical before/after, unattributable-mount stderr report demonstrated, both zip offset conventions verified on the backport, kitmountpoint.test 4/4, full suite at the exec-14.3-only baseline). Index entry moved to GOALS-archive. Reference sweep: achieved/archive markers added at the G-129 mentions in G-101, G-024, G-130 and G-131 (pending-tense Approach line rewritten); forward-pointing notes pushed to their targets - G-131 gets the factored-derivation shape, measured mount tables, app/main.tcl hook and the LUCK both-capability probe row; G-123 gets the bin/AGENTS.md kit-wrappable requirements as its publication criterion pointer. Claude-Session: https://claude.ai/code/session_01UEgomWq6kA6c4A8GswqqGW Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
59f14d8e46 |
G-129 activated (user-directed): kit-boot mount-point derivation begins
Index entry + detail mirror flipped proposed->active. Activation-freshness overlap survey (goals_xref score G-129) found one relationship drafted since the goal was written: G-130 points here with no back-pointer - recorded as a Related: note in the detail file. Claude-Session: https://claude.ai/code/session_01UEgomWq6kA6c4A8GswqqGW Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
4 days ago |
|
|
2dd63fa700 |
G-129 + G-101: downstream back-pointers to G-131
Both pairs read as one-directional in goals_xref (G-131 -> G-129 scoring 3.55, G-131 -> G-101 scoring 2.03) because the dependency convention has the consumer point at its predecessor. Adding the reverse edge so a reader who opens G-129 or G-101 - the two goals likely to be activated first - sees what is waiting downstream. Non-contract Notes only; neither goal's Goal or Acceptance changes, and both still stand alone. G-129: G-131 generalises its derivation from "where is the zipfs image mounted" to "which container is attached at all". That does not change what G-129 delivers, but it does say something about HOW - keep the derivation factored as a step that answers a question about the running kit rather than inlining a zipfs assumption into the surrounding path assembly, so the metakit arm can be added beside it rather than around it. G-101: this is the more consequential one. G-131 wants a runtime that boots from EITHER container, which bears on how G-101's decision should be FRAMED - if G-131 is wanted, the useful outcome is not "pick one container for 8.6 and close the question" but "establish that metakit is carryable AND that the zipfs backport is carryable, and record which is the default". The file already surveys both candidates and both look additive; the two sections were written independently as competing options, and G-131 is the reason to read them as a possible pair. Recorded explicitly that this does not block G-101's decision - it can still be decided without committing to G-131. goals_xref now reports both pairs as linked. Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
4 days ago |
|
|
df83b21a24 |
bootsupport: replace mounted modpods by delete-then-place, and explain the windows catch-all (punkshell 0.27.4)
'make.tcl bootsupport' failed three times this session replacing the zip-based
punk::mix::templates modpod, always with:
error copying "<src>" to "<dst>": invalid argument
Root cause, demonstrated rather than inferred. A zipfs mount MEMORY-MAPS its archive
(tclZipfs.c CreateFileMappingW + MapViewOfFile), and windows refuses to overwrite a file
with a user-mapped section open - ERROR_USER_MAPPED_FILE (1224). Any holder blocks it: a
running punk shell that loaded the modpod, a src-mode session, or the build itself.
Reproduced directly: the same file copies fine unmounted, fails while zipfs-mounted, and
copies fine again once unmounted.
The message is a dead end BY CONSTRUCTION, which is why two earlier attempts at
characterising this (in commit messages and in the archived G-124 detail file - first "a
modpod make.tcl has itself mounted", then "a transient lock") were both wrong in different
ways. Tcl_WinConvertError maps only Win32 codes 0..267 and sends everything above them to
errorTable[1], which is EINVAL - so EVERY high-numbered windows error surfaces as "invalid
argument", naming neither cause nor remedy. Byte-identical code in 8.6 and 9.1b1.
FIX. ::punkboot::replace_possibly_mapped_file tries the ordinary copy and, on failure,
falls back to DELETE-THEN-PLACE, which windows does permit: unlinking a mapped file leaves
the holder reading its own mapping while new content lands at the name (measured: delete
succeeds while mounted, the mount keeps serving its old content afterwards). Replacement
content is staged to a sibling <target>.punkboot-new first, so a mid-sequence failure can
never leave the target missing; a 'broken' return - unlinked and unrestorable - is reported
as a build failure naming the file to restore by hand. This replaces a narrower prior
workaround that only recognised the already-identical case and otherwise recorded FAILED.
DIAGNOSIS. ::punkboot::mapped_file_hint fires when a genuine failure carries the catch-all
message and explains what it actually means and which process class to look for, instead of
leaving "invalid argument" bare. It stays silent for unrelated errors.
Verified on the real failure: the bootsupport run that has failed all session now reports
"(in-place overwrite refused - replaced by delete-then-place; target was memory-mapped, e.g
a mounted modpod)" and completes, with no hand-copy and no rerun. Helper-level checks cover
the unmapped path (plain copy, unchanged), the mapped path (recovers, content correct,
holder's mapping intact, no temp left behind) and both hint branches. Full suite 1167 tests,
1146 passed, 1 failure - core/tcl exec-14.3, the documented baseline.
Documented in src/bootsupport/AGENTS.md, including the general warning that 'invalid
argument' from ANY windows file operation in Tcl means "some windows error above 267" and
must never be read at face value.
Also drafts G-132 (user-approved): the errno catch-all is upstream's defect, not ours, and
deserves reporting. The goal is deliberately shaped so an AGENT DRAFTS AND THE DEVELOPER
SUBMITS - no account use, no web form, no API - following the G-039 precedent, with the
submission-ready text staged in TEMP_REFERENCE and the finding, reproducer, eventual ticket
URL and disposition kept in the tracked detail file, because TEMP_REFERENCE is one
'git clean -xdf' from gone. The report's claim is deliberately narrow: the errno conversion
is plainly wrong, while the related fact that 'file copy -force' over a mapped file succeeds
on unix and fails on windows rides along as context rather than as a second demand.
punkshell's workaround is explicitly not removed if upstream fixes it - an upstream fix
dates it rather than deletes it.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
|
4 days ago |
|
|
226b691471 |
G-130 + G-131 drafted (user-approved); G-129 records why it stands alone
Two goals from the third-party 32-bit kit investigation, plus the finding that kept G-129 independent. G-129 Notes: the developer asked whether G-129 is needed to support baking with third-party kits. It is - it is the LAST blocker. The chain is: read the runtime's attached payload (G-124, achieved), do not let the boot-precondition gate falsely refuse it (G-125, achieved, plus the punkboot::utils 0.4.0 third-convention fix), then have the baked kit FIND that payload at boot (G-129). Measured by running punk_main.tcl's detection logic verbatim under bin/runtime/win32-ix86/tclsh8.6.10-luck-zip.exe: has_zipfs is 0, the //zipfs:/app branch is never computed, the kitpath branch is skipped, and NO internal module or lib paths are added - while tcl::zipfs::mount really does report the archive mounted at the exe path. So the failure is not "mounted somewhere unexpected and mis-resolved", it is "concluded there is no zipfs at all". This corrects an earlier recommendation to fold G-129 into G-131: folding would have parked third-party kit baking behind a much larger goal that needs a runtime carrying two container capabilities, which in turn needs G-101's port work. G-130 - 32-bit windows runtimes from the buildsuites, both Tcl generations. The motivation is supply, not architectural completeness: old, firewalled or sandboxed systems (industrial ones especially) are where 32-bit persists, they cannot fetch what they need, and a machine carrying binary Tcl modules built for only one major forces the runtime to match the modules. No single supplier keeps current 32-bit windows Tcl available for both majors. Acceptance keeps the binary-extension gate the developer asked for - each runtime must LOAD a real 32-bit extension, not merely start - because accepting drop-in modules is the whole point; twapi 4.7.2 inside the LUCK runtime is a 32-bit dll already in the tree for the 8.6 side. Both generations are required before the goal is met, since the motivating case is precisely that the machine's modules dictate the generation. KIT/CONTAINER TYPE IS DELIBERATELY OUT OF SCOPE - this goal produces runtimes, not kits; that question is G-101's. Sequencing per the developer: before or around the FreeBSD work, because a bitness change is likelier to surface recipe assumptions than another OS at the same bitness. Recorded as verified: punk::platform::local already reports win32-ix86 from a 32-bit interpreter and make.tcl derives the matching host/target/store, so no platform-canon work is needed. G-131 - one runtime, either payload: boot-time container autodetection (metakit or zipfs). Today a runtime's container is fixed when the runtime is ACQUIRED, so deliverables multiply by container: per platform, per generation, per container. If the boot detected what is attached, the container would become a bake-time choice and the count would collapse to platform x generation. Drafted to EXTEND G-129 rather than supersede it, and to depend on G-101 for the metakit arm to exist at all on a suite-built runtime. Its zipfs obligation is only that G-129's derivation still holds when reached through container detection. Carries two constraints found during the survey: the design must be preinit-shaped from the start, because G-101's Tcl 9 survey found the proc tclInit override the tclkit lineage relies on is dead in 9.1 and tcl_libPath is gone; and it explicitly rejects KitCreator's compile-time KIT_STORAGE_MK4/_ZIP/_CVFS switch - the closest prior art - because a compile-time answer still produces one binary per container. Scope names src/make.tcl's kit_type_mismatch check, whose premise (a runtime implies one container) this goal makes false. cookfs and other exotics are out of scope by the developer's decision. Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
4 days ago |
|
|
176f2ad702 |
punk-runtime list/use stop offering support files as runtimes (punkshell 0.27.3)
'bin/punk-runtime.cmd list -platform win32-ix86' listed a LUCK.url shortcut and a tclsh8.6.10-luck-zip.cfg build request as if they were selectable runtimes. Both payloads already filtered support files - .txt/.toml/.tm/.tmp/.log - so the mechanism existed and only the recognised set was too narrow. It was also duplicated across NINE filter sites in three syntaxes (a powershell array, a bash case pattern, a bash grep -E regex), and two of them had already drifted: the "not a selectable runtime" guard omitted .log and matched *_BUILDCOPY without a trailing wildcard. The set is now defined ONCE per payload - $PunkRuntimeSupportExt / Test-PunkRuntimeSupportName in the ps1, punk_support_ext_re / is_punk_support_name in the bash - and every site consults it, so the two payloads cannot drift apart. Their listings are required to agree byte-for-byte and now do so by construction. Recognised support files, by category: docs/text (.txt .md .html .htm .pdf .url), config/metadata (.toml .json .xml .yml .yaml .ini .cfg), dev leftovers (.tm .tmp .log .bak .old), checksums/signatures (.sha1 .sha256 .asc .sig) and archives (.zip .tar .gz .bz2 .xz .7z), plus any *_BUILDCOPY* name. Anything else is still treated as a runtime candidate - deliberately, so a stray binary is visible rather than silently hidden. Verified: the win32-ix86 listing drops from 6 entries to the 4 real runtimes; the bash helpers produce the identical four (the polyglot routes msys bash to the ps1 payload on windows, so the bash side was exercised directly). Re-wrapped per bin/AGENTS.md with checkfile ERROR-free; runtimecmd_roundtrip (byte-identity), runtimecmd_checkfile, runtimecmd_freshness (10/10, both payloads against the fixture server) and runtimebash_wsl (8/8) all pass, as does the full suite at its documented baseline. bin/runtime/README.md now states what a platform folder is FOR (a store tier keyed by the platform a runtime is for, not by this machine) and what is tolerated in it, with the recognised-support-file table and the warning that anything else will be offered as a runtime. It is force-added to git: /bin/* is ignored and a ! negation cannot re-include a file inside an excluded directory, so git add -f is the only mechanism - recorded in the .fossil-settings/AGENTS.md force-tracked one-off list, whose fossil counterpart is an explicit 'fossil add' at the next catch-up checkin. Also records in G-101 a survey of TEMP_REFERENCE/androwish for the zipfs-on-8.6 question the developer raised (non-contract findings; pointer added to TEMP_REFERENCE/AGENTS.md per its contract so the survey is not repeated). The undroidwish zipfs backport is ADDITIVE - generic/zipfs.c (6586 lines) + zipfs.h + a library/zipfs1.0 dir + one object line in the win and unix Makefiles - so it is carryable as a suite patch rather than a fork; it is C rather than C++ like mk4tcl; Tcl_StaticPackage registration is gated on ZIPFS_IN_TCL / ZIPFS_IN_TK, i.e. designed to compile into tcl or tk; and it is Christian Werner's, under the tree's Tcl-style license.terms. Its capability delta against Tcl 9 zipfs is recorded (no 'root', no ::zipfs ensemble, and not registered in child or thread interps), as is the exe-path mount convention that motivates G-129. Provenance of our specimen is established: LUCK is a CGI repacker that selects packages out of a prebuilt vanillatclsh binary's ZIP, so bin/runtime/win32-ix86/tclsh8.6.10-luck-zip.exe is a repack of androwish's own build - a working existence proof of zipfs-on-8.6 rather than a claim. Three open questions are recorded rather than guessed: whether it applies to 8.6.18 (the tree is 8.6.10), whether it builds under the pinned zig, and where the boot-time self-mount hook lives - stock tclAppInit calls Tclzipfs_Init only under #ifdef TCL_TEST, so it is in the vanillatclsh/undroidwish application main, which is also the hook a dual-container autodetecting boot would need. Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
4 days ago |
|
|
8cbdf86fff |
G-129 drafted (user-approved): kit boot finds its payload wherever the archive mounted
Arising from the third-party 32-bit kit investigation. src/vfs/_config/punk_main.tcl decides whether the running kit has an attached zipfs image with two assumptions that held for every runtime punkshell had until now: it probes with 'info commands tcl::zipfs::root' and then looks for the mount at a compiled-in //zipfs:/app. Christian Werner's androwish / undroidwish backport gives Tcl 8.6 a working zipfs but no 'root', and mounts the executable's attached archive at the EXECUTABLE'S OWN PATH, so [info library] reads <exe>/tcl8.6. Against such a runtime punkshell concludes "no zipfs", neither the zipfs nor the kitpath branch runs, and the kit silently gets no internal module or lib paths at all - the failure surfaces later as packages that cannot be found. project_main.tcl carries the identical code, so the same defect ships into every generated project; both files are in Scope. Two third-party 32-bit runtimes now in the win32-ix86 tier bracket the problem and are named as the verification pair: tclsh8.6.10-luck-zip.exe (Lean Undroidwish Construction Kit - no 'root', no ::zipfs ensemble, mounts at the exe path, library at tcl8.6/, and no zipfs at all in child or thread interps) and tclsh9.1b0-tclsfe.exe (apnadkarni/tcl-sfe - the modern //zipfs:/app convention on the same architecture). The Acceptance requires both: the tclsfe kit proves the 32-bit target itself needs nothing special and that the derivation did not regress the ordinary case, the LUCK kit is the actual work. Both are untracked per G-004, so tests naming them self-gate on presence as the G-124 piperepl pin does; the LUCK build is reproducible from its .cfg build request. Approach settled in the draft: derive the mount point from tcl::zipfs::mount itself, whose entries pair mountpoint with mounted file - the entry naming this executable is this kit's archive wherever it landed. Detect zipfs by a command the backport also provides rather than by 'root'. Leave the kitpath and cookfs branches alone. Report on stderr when an archive is attached but no mount entry matches this executable, because silence is today's failure shape and is what made this expensive to diagnose. Overlap survey named G-031 (restructures this same file into a thin main plus shared boot core - whichever lands second adopts the other's shape, and the derivation belongs in the core), G-101 (its candidate container list already includes zipvfs-over-tclvfs boot, and the LUCK runtime is a ready-made specimen carrying zipfs, vfs 1.4.2 and starkit together), G-123 (these are punkbin candidates; kit-wrappability decides whether a runtime publishes as a usable tier), G-125 (achieved - its gate learned the tcl<M>.<m>/ library convention so such a kit can now be BUILT; making it BOOT is this goal), plus G-114 and G-127 as deliberate non-overlaps - same file, different axes. Also records in G-024 a design direction from the developer (non-contract Notes): the toml move is where NAMED GROUPINGS of mapvfs entries should be considered, prompted by wanting verification kits active but obviously not shipped products. Grouping would also give bake and bakelist a name to select on beyond per-kit names, and the commented-out historical entries somewhere honest to live. Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
4 days ago |
|
|
ec781d7019 |
punk::libunknown 0.2.3: pkgIndex.tcl scripts run in the global namespace again (punkshell 0.27.1)
A third-party 8.6 kit under evaluation (Lean Undroidwish Construction Kit, 32-bit windows)
could not load its own bundled twapi 4.7.2 inside punkshell:
P% package require twapi
invalid command name "twapi::set_scriptdir"
("package ifneeded twapi 4.7.2" script)
twapi's pkgIndex.tcl defines 'namespace eval twapi { proc set_scriptdir ... }' when the
INDEX is sourced, and its ifneeded script calls that command at require time. The command
existed - as ::punk::libunknown::twapi::set_scriptdir. punk::libunknown 0.2.0 moved index
sourcing out of 'namespace eval ::' into source_pkgindex, a proc of the punk::libunknown
namespace, to stop each index's helper variables leaking into the global namespace and to
stop a user global named 'dir' being clobbered. That fixed the frame, but a proc body
executes in ITS OWN namespace, so an index's RELATIVE 'namespace eval foo' started
creating ::punk::libunknown::foo instead of ::foo. Stock tclPkgUnknown is a proc in ::,
so indexes have always had global resolution; the ifneeded script, evaluated later at
global scope, then looked for a command that was never there.
The body now runs via apply with :: as its namespace argument, which gives both
properties at once: a local frame (index helper variables still discarded, user 'dir'
still safe) and the global resolution context indexes are written against.
Not twapi-specific: any index that defines commands or namespaces at source time for its
own ifneeded scripts to use hits this, and the pattern is common in third-party indexes.
punkshell's own vendored twapi 5.0b1 happens to avoid it (self-contained 'apply' ifneeded
scripts), which is why the tree never surfaced it.
Verified on the LUCK 8.6.10 runtime end-to-end - 'package require twapi' at the punkshell
prompt now returns 4.7.2 with ::twapi::scriptdir correctly set - and pinned generically by
pkgindex_relative_namespace_is_global in the discovery suite, whose new fixture copies
twapi's pattern so no third-party kit is needed. The pin was proven to bite: driven
against the pre-fix body the same fixture fails with 'invalid command name' and leaves
::punk::libunknown::pklu_nsindex behind; against 0.2.3 it resolves and leaves nothing.
Full suite 1165 tests, 1144 passed, 1 failure - core/tcl exec-14.3, the documented
baseline.
Manual-version bump per src/modules/AGENTS.md: file renamed, Meta line, manpage_begin and
provide-block updated, version-history line appended. The rename sweep converted the two
goal Scope references (G-035, G-109) from the exact filename to the glob form
src/modules/punk/libunknown-*.tm that GOALS.md's own Scope-authoring guidance recommends,
so the reference stops drifting at every bump.
Also records in G-035 the mechanism behind its "avoid mixing .tm and pkgIndex.tcl
provision" folklore, which this investigation identified (non-contract Notes). Stock
::tcl:™️:UnknownHandler returns early when $satisfied is set and therefore never falls
through to ::tclPkgUnknown, so a require satisfied from a .tm suppresses the whole library
scan. Measured with a synthetic fixture on both 8.6.10 and 9.0.3: with mixpkg 1.0 as a .tm
and mixpkg 2.0 in an auto_path library under 'package prefer latest', stock returns 1.0
and reports only 1.0 from 'package versions', runs no index side effect and registers no
sibling package; the libunknown chain returns 2.0 and does all three. libunknown already
neutralises it - its handler still computes $satisfied but the early return is commented
out - and that unconditional fallthrough is exactly what the epoch cache pays for. The
folklore is therefore substantiated for stock Tcl with a named failure mode (silent
older-version selection) and neutralised under the punkshell chain, with stock behaviour
still reachable in any interp that has not run punk::libunknown::init.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
|
4 days ago |
|
|
b7c632b670 |
G-125 achieved: a kit that cannot boot is not deployed (punkshell 0.27.0)
The kit machinery already knew when it had failed to extract anything from a source
runtime, and under G-122 that notice became a recapped BUILD-WARNING - but the build
still assembled an artifact, DELETED the deployed kit and copied the new one over it,
closing running instances of the kit first. Field-observed 2026-07-26: an msys2-hosted
bake of punk91 produced a 49,501,792-byte bin/punk91.exe that failed at startup with
"application-specific initialization failed: Cannot find a usable init.tcl", by which
point the previously working kit was already gone. G-124 removed the particular cause;
this removes the class. A build tool should not make a working executable worse.
A bake now refuses any kit whose merged .vfs supplies no tcl library: the kit is listed
under FAILED KITS with a reason naming the cause and NOTHING is written - no
src/_build/<kit>, no deploy, and the previously deployed bin/<kit> is left byte-identical.
The gate sits immediately after the _vfscommon.vfs + <kit>.vfs merges and before the
kit-type assembly switch, the last point at which no build product exists; a refusal
appends to failed_kits, ends the punkcheck event FAILED and continues, so the punkcheck
records stay consistent with what is on disk. The merged src/_build/<kit>.vfs tree is
deliberately left behind - it is the evidence for the refusal.
It gates on the BOOT PRECONDITION, not on the extraction step having run. Some .vfs
folders legitimately supply their own tcl library (src/vfs/punk8_statictwapi.vfs,
punk9test.vfs and mkzipfix.vfs do today), and those must keep building - so the check
reads the merged tree. It is structural and executes nothing, which also makes it valid
for cross-target kits this host could never run, and costs 0.63ms per kit (measured over
200 iterations against the real src/_build/punk905.exe.vfs), so it runs unconditionally.
The predicate is punkboot::utils::vfs_boot_library_report (0.2.0 -> 0.3.0), called through
a guarded require modelled on the existing get_src_provenance_warnings: a stale or missing
bootsupport snapshot degrades the gate to a NOTE rather than failing every kit. Both
branches were observed live - before the bootsupport propagation 'make.tcl check' reported
UNAVAILABLE, after it ACTIVE. Scope was extended at activation (user-approved) to put the
predicate in that module rather than private to the build script, because a gate that
cannot be exercised cannot be characterized, and punkboot::utils is already where
make.tcl's provenance gate helper lives.
What qualifies as a tcl library: tcl_library/init.tcl (zipfs-attached kits) or
lib/tcl<major>.<minor>/init.tcl (starkit-style), AND at least one companion file beside it
(tm.tcl, package.tcl, auto.tcl, clock.tcl, history.tcl, word.tcl) or an encoding/
directory. The companion test is load-bearing: every punkshell kit carries
lib/BWidget1.10.1/init.tcl, so a check that looked for any init.tcl anywhere would pass a
kit with no tcl library at all. lib/tcllib2.0 is correctly not matched by the lib/tcl[0-9]*
glob. Verified against all 10 assembled trees in src/_build - both conventions are
represented (tcl_library for punk902z/punk905/punk91/punk9_beta/punk9bi_beta/punkmagic,
lib/tcl8.6 for punk86/punkbi/punksys, lib/tcl9.0 for punkshell902).
The no-extraction BUILD-WARNING was reworded from "will not initialise unless src/vfs/<x>
supplies one" - a consequence the build then ignored - to "will FAIL the boot-precondition
gate unless src/vfs/<x> supplies one". It stays a warning rather than becoming the failure,
because a .vfs that supplies its own library needs no extraction.
Verified 2026-07-27 end-to-end against a temporary fixture kit (a mapvfs entry pointing a
zip kit at a payload-free runtime, plus a vfs with no tcl library), with sentinel files
standing in for a previously deployed kit and a previous build product. Across the failing
run bin/punkgatefixture.exe (sha1 2a0700eb...) and src/_build/punkgatefixture.exe (sha1
12c50567...) were byte-identical with unchanged mtimes, and the kit was reported under
FAILED KITS with the cause named. Adding tcl_library/{init.tcl,tm.tcl} to that same fixture
vfs - extraction still yielding nothing - made it build and deploy normally, which is the
other half of the criterion. The fixture was removed afterwards and mapvfs.config restored
byte-identical to its backup. Real-kit bake through the gate: punk905 builds, deploys and
boots.
Characterization: 12 tests in modules/punkboot/utils/testsuites/utils/bootlibrary.test
(both conventions, the companion-file requirement and its BWidget decoy, near-miss
reporting, missing/empty trees, and a sweep asserting every assembled src/_build/*.vfs
tree still passes so the gate cannot fail kits that boot today) and 2 in
shell/testsuites/punkexe/maketclbootgate.test (the ACTIVE/UNAVAILABLE report, ESC-free per
the G-113 piped policy). Existing punkexe suites pass unchanged.
Documented in src/AGENTS.md with the remedy when a kit is refused, in ARCHITECTURE.md
beside the provenance gates, and in the embedded 'make.tcl workflow' data flow as key note
K10 (verified under the default and PUNKBOOT_PLAIN=1 paths, within the 100-column budget).
The achieved flip archives the entry and the detail file, and sweeps the live tier: G-127
(its output location inherits the never-written guarantee as long as the gate stays
upstream of the artifact write, and its payload/target mismatch reporting should share this
vocabulary), G-028 (the sibling "why bin/<kit> was not updated" surface in the same deploy
step) and G-101 (a new container type must land its library where the gate looks, or extend
the location list).
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
|
4 days ago |
|
|
78d9bf238a |
G-124 achieved: dependency-free zip reading in punk::zip (punkshell 0.26.0)
punk::zip could write a zip and split an executable-prefixed one, but nothing in the tree
could READ a zip without zipfs, vfs::zip or tcllib's zipfile::decode - a system package
punkshell does not vendor, with exactly one consumer: make.tcl's zipfs-less kit
extraction. Measured at drafting: msys2's /usr/bin/tclsh8.6 has no tcllib, so a bake
driven from that host could not lift the runtime's own zip (its tcl_library) into the kit
and the artifact did not boot.
punk::zip 0.1.1 -> 0.2.0 adds three commands, stock Tcl only. archive_info reports where
the archive begins inside its host file and which offset convention it uses; members
walks the central directory and returns one dict per entry without decompressing
anything; unzip extracts all or part of it with every member's crc32 verified,
directories materialized, and the writer's 2MB whole-member-vs-streaming threshold
mirrored. All three accept a plain .zip or a zip attached to an executable or script
prefix, so "what is inside this kit / runtime / modpod" is now answerable on a runtime
without zipfs.
The offset derivation is stated once and shared: offsetbase = cdiroffset - diroffset.
Positive means an external preamble with archive-relative offsets, zero means the offsets
are file-relative (or there is no preamble); dataoffset is the split point either way.
Because every surface reads the ORIGINAL file at that base, the file-relative shape stops
being a special case - the broken split-off intermediate is never produced.
tclsh90b4_piperepl.exe is the store's one file-relative artifact: the old
split-then-tcllib path still fails on it with exactly "Bad zip file. Bad closure.", and
it now extracts all 841 members crc-verified in 735ms.
extract_preamble consumes that machinery instead of carrying its own scan, and two
defects went with the refactor: it read 28 bytes of a 30-byte local file header, and it
derived the file-relative base from the FIRST central directory record only (its own
'#todo! loop through all cdr file headers'). The shared walk takes the minimum over ALL
records and then validates that a PK\3\4 really sits there. Its five puts stdout debug
lines are gone.
Refusals are decided for every selected member before any file is opened, so an
unsupported archive cannot leave a half-populated directory: encrypted entries, zip64
size/offset fields, unknown compression methods, crc mismatch (partial file removed) and
member paths that would escape the target are each named. Store and deflate only,
mirroring the writer's own primitives.
make.tcl's zipfs-less extraction now calls punk::zip::unzip on the original runtime and no
longer creates the extracted_<runtime>.zip intermediate. No punkshell code requires
zipfile::decode any more. Two categories of hit remain and are deliberate: tcllib's own
zip/decode.tcl shipped as a LIBRARY inside some .vfs payloads, and one guarded optional
probe inside the vendored third-party ooxml1.10/ooxml.tcl.
First tests punk::zip has ever had (src/tests/modules/punk/zip/), covering the three
archive shapes from one source tree, the introspection output, the named refusals, and
the mkzip -> read round trip - the first coverage that what punkshell WRITES is readable.
Verification, all 2026-07-26. Reference host for the dependency-free claim: msys2
tclsh8.6 8.6.12, probed as zipfs / vfs::zip / zipfile::decode all ABSENT - suite driven
there harness-free, 28 passed, 2 skipped (the zipfs-gated cross-checks only), 0 failed.
30/30 under Tcl 9.0.3, 28 + 2 skipped under native 8.6. Full source-tree suite after the
change: 1142 tests, 1 failure - core/tcl exec-14.3, the documented baseline. Independent
cross-check: 868 members of tclsh905.exe extracted byte-identical against the same
archive mounted with tcl zipfs. Bake demonstration: 'bake -confirm 0 punk905' driven by
the msys2 tclsh8.6 (host=msys-x86_64, target=win32-x86_64) produced
extracted_tclsh905.exe/{tcl_library,lib} with no intermediate .zip, and the deployed kit
boots with tcl_library at //zipfs:/app/tcl_library, 95 encodings, msgcat 1.7.1, http
2.10.2 - and reads itself with the new reader.
Trap worth keeping: zlib stream inflate's 'get' returns only what the stream has already
produced, so one get per put silently truncates a large member to the first few chunks
(measured 327680 of 5048890 bytes on both 8.6.12 and 9.0.3). The inner drain loop is
load-bearing, and the >2MB streaming test exists to catch its removal.
Standing question answered and pinned: zipfs does NOT misidentify punk::zip::mkzip
directories. It keys on the trailing slash (which punk::zip::walk always emits), not the
stored permission bits, exactly as the current cli-999999.0a1.0.tm wording says - the
older, less precise wording survives only in frozen module snapshots under
src/vfs/mkzipfix.vfs and src/vfs/project.vfs. The real difference from zipfs mkzip is
that zipfs writes no directory entries at all.
The achieved flip archives the entry and the detail file, and sweeps the live tier: G-034
(the reader is its extract-rather-than-mount alternative, plus the measured finding that
make.tcl on 8.6 cannot mount its own templates modpod), G-101 (the read half of a
zipfs-less 8.6 container is solved), G-125 (the gate now has a named failure reason to
report), G-126 (the member-dict keys and fixture set its parity suite must reproduce, and
a back-pointer to G-128 whose only recorded bridge was this goal), G-128 (archive_info
answers "is this artifact safe to move the overlay of?" in one call).
One acceptance clause is reported for review rather than claimed silently: "NO
zipfile::decode requirement remains anywhere in the shipped tree" is satisfied for
punkshell's own code, with the vendored-third-party residue named above.
The archived detail file's diff is a rename plus the flip's evidence write-up.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
|
4 days ago |
|
|
78b6f47805 |
G-127/G-128 drafted + G-057 amended (user-approved): cross-target vfs bake, portable PE stamping, icon sidecar and mechanism seam
Follow-on goals from the G-122 host/target split, each drafted with its overlap survey
and approved before writing. The G-057 contract edit (title, Scope, Goal, Acceptance) was
shown clause-by-clause and approved per the proposal-first rule.
G-057 amended - the goal was drafted before G-122 separated host from target, so its skip
condition read as one host-shaped test ("non-Windows platform skips") while its Notes used
target language. Split in two: a target with no PE resources is NOT APPLICABLE, a windows
target on a host that cannot run twapi is a distinct shortcoming. Both still emit a text
sidecar, now produced for every kit on every target and defined so the parked RT_VERSION
follow-on extends the same file rather than adding a second. Embedding sits behind a
single mechanism seam, and the twapi arm is explicitly PERMANENT - the seam selects
between mechanisms, it does not replace one: twapi is vendored and git-tracked
(src/vendorlib_tcl8|9/win32-x86_64/twapi-5.0b1) and reachable from make.tcl's auto_path,
so a fresh windows checkout that fetches a runtime and bakes gets icons with no build
toolchain (probed under a stock tclsh 9.0.3 and a fetched plain family runtime). The
per-vfs override is settled as shared across a kit definition's targets with no target
dimension.
G-127 - cross-target bake of a custom .vfs. G-122 made the build READ the right runtime
for a target; this makes it WRITE the right kit for one. Three measured gaps: output is
flat, so two POSIX targets of one kit collide (within a run the duplicate guard renames by
RUNTIME not platform; across selective runs exe_names_seen resets and the second
overwrites the first); the payload model is one hand-curated folder per target
(punk9linux.vfs, not a vfslibs participant, with vendorlib_vfs.toml hardcoding the
platform into its source path - a shape inherited from G-037 when there was one target);
and nothing verifies payload against target. Non-native kits go to bin/kits/<platform>/
with native staying at bin/<name>; /bin/* already ignores it so no dual-track ignore work.
Records that G-114 and G-115 overlap yet never reference each other - the platform axis
and the payload axis have never been connected.
G-128 - portable PE resource stamping via a vendored zig tool, plugging into G-057's seam
without retiring its twapi arm. Feasibility measured: zig rc (resinator, bundled in the
0.16 toolchain) is a resource COMPILER supplying the RT_GROUP_ICON/RT_ICON structure
reference, not a patcher - we never link these runtimes, so patching an existing PE is the
work. In our runtimes .rsrc is not the last section (.reloc follows), so the
implementation appends a section and repoints the resource data directory, which shifts
the overlay: safe for an archive-relative zip, not for a file-relative one, so the unsafe
case is refused rather than corrupted. The payoff beyond portability is post-hoc stamping
of a finished kit, which removes G-057's icon-before-append ordering constraint. Its
distribution is settled as buildable from vendored source AND publishable as a punkbin
artifact, so the no-toolchain route need not depend on the committed twapi (the G-004
tension).
Also adds non-contract Related back-pointers in G-057 to G-122/G-127/G-128.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
|
4 days ago |
|
|
e1711a7b2a |
G-124/G-125/G-126 drafted (user-approved): punk::zip reader, unbootable-kit deploy gate, vendored punkzip accelerator
Three goals arising from the G-122 work, each drafted with its overlap survey and approved before writing. G-124 - dependency-free zip reading in punk::zip. Nothing in the tree can READ a zip without zipfs, vfs::zip or tcllib's zipfile::decode, which is a system package punkshell does not vendor and which has exactly one consumer: make.tcl's zipfs-less kit extraction. The goal removes that requirement outright (not as an optional fallback), adds an introspection surface so punk::zip is useful to script programmers, and gives the writer its first round-trip coverage. Measured motivation recorded in the detail file: msys2's tclsh8.6 has no tcllib and so bakes an unbootable kit, and extract_preamble's live '#todo - need to adjust offsets' means a FILE-relative prefixed executable (tclsh90b4_piperepl.exe) splits into a .zip tcllib rejects with "Bad closure" - reading the original file at its derived base offset removes that failure mode by construction. G-125 - a kit that cannot boot is not deployed. Today a failed extraction emits a recapped BUILD-WARNING and then deletes and replaces the deployed kit anyway; field- observed 2026-07-26 replacing a working punk91.exe with one that dies on init.tcl. The gate tests the boot precondition on the assembled vfs, so a kit whose payload legitimately supplies its own tcl library still builds. G-126 - punkzip as a VENDORED zip accelerator behind G-124's pure-Tcl floor, with zig kept optional (a tclsh-only clean checkout must still build and bake). Feasibility measured and recorded: the source builds clean under its declared zig 0.15.2, and under 0.16 fails on one surfaced error (std.process.argsAlloc), with the OS-facing surface confined to 3 of ~20 files while the ~10k-line compression core is untouched; zig 0.16.0 is already unpacked in bin/tools. Benchmarks captured for the speedup claim. Non-contract Notes back-pointers added to G-034 (the reader is a candidate for its own Acceptance's "alternative modpod mount path" branch) and G-101 (an 8.6 container has no zipfs, so it needs a reader that works without one). Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
5 days ago |
|
|
04d2a51b67 |
G-122 achieved: make.tcl bakes by target platform, not host personality (punkshell 0.25.0)
Everything a bake EMITS is now keyed by the artifact's TARGET platform rather than the driving tclsh's personality: the bin/runtime/<tier> store a runtime is read from, .exe suffixing of runtime files and kit outputs, presence checks, and whether the pre-deploy process sweep uses tasklist/taskkill or ps/kill. Host semantics - copy commands, path handling, filesystem case rules, prompts - stay keyed to the host. The default target is the host's platform canon EXCEPT for a cygwin-family host (an msys2/cygwin-runtime tclsh, which reports tcl_platform(platform) unix on windows), which targets win32-x86_64. Such a host now drives the identical kit set, names and store addressing as a native tclsh; before, it reported every kit runtime=missing against a nonexistent mingw64-x86_64 store. mapvfs.config entries take an optional 4th element naming the kit's target platform, so a runtime kept in another platform's tier is a first-class mapping entry. The linux tclkit entry now declares linux-x86_64 and bakes to a suffixless bin/punkshell902. Zip-type kits assemble without zipfs in the driving tcl: when tcl::zipfs::mkimg is absent (any 8.6) the image is built by raw-runtime split + punk::zip::mkzip + concatenation - the same helper the zipcat type uses. Both mount identically (archive-start-relative offsets). Fixes exposed by the above: the runtime capability probe looked for a suffixless filename and so reported find-fail for every runtime on windows; with real capabilities arriving, the extraction try-list was found to test capability presence rather than value, which would send a plain zipfs runtime down the kit path where a failed sdx mksplit replaces raw_runtime with the un-split original; BUILDCOPY names now follow the runtime's own filename; runtime map keys strip only .exe (file rootname would eat the last dotted segment of tclsh9.0.5); and native windows command lines run through a guard suppressing msys2's posix-path argument rewriting - without it taskkill /PID <n> reached taskkill as taskkill C:/<msysroot>/PID <n>, so the sweep could find a running kit but never replace it. punk::platform folds the msys2 family (mingw64/mingw32/ucrt64/clang*) onto one stable 'msys' tag and CYGWIN_NT onto 'cygwin' - msys2's uname renders that token from MSYSTEM, so one binary otherwise canonizes differently per launching shell. New normalize_os; cygwin-x86_64 added to the platform table; 'help platforms' documents the fold. make.tcl check reports the derivation on one line; bakelist rows carry target=<platform> for non-default targets and the detail block names the tier; workflow text gains key note [K9]. New characterization suite maketclplatform.test (5 tests, two self-gating on discovering and probing a real msys/cygwin tclsh). Full suite 1112 tests: 1093 passed, 18 skipped, 1 failed = the documented exec-14.3 baseline. Verified: msys2 tclsh8.6 bakelist output identical to native Tcl 9; a changed punk91 baked and deployed from that host with the sweep killing a running instance msys ps cannot see; a real cross-target linux kit baked from windows to a 24MB ELF; a zipfs-less 8.6 bake producing a bootable zip kit. Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
5 days ago |
|
|
a5edfe17b6 |
G-101 Scope: sync both tiers on the survey-extended wording
The pre-activation survey (
|
5 days ago |
|
|
f4031b209f |
G-101 pre-activation survey: reference inventory + sdx wrap.tcl provenance capture
Notes-only on the goal; the new tracked material is the sdx patch capture. G-101 gains four sections and an extended Scope line naming the surveyed trees and bin/sdx.kit: a reference-material inventory giving the metakit boot chain in reading order with file:line anchors (kbskit kitInit.c pre-init -> boot.tcl raw mk::select bootstrap -> setupvfs.tcl -> mk4tcl.cpp Mk4tcl_Init, with KitCreator's storage-switch variant as the comparison reference for scoping cookfs/zipvfs); sdx provenance; the self-mount shadowing gotcha; and metakit-under-Tcl-9 feasibility. Two findings bear on the container choice: 8.6's core zlib cannot do mk4vfs streaming (kbskit boot.tcl states it - forces whole-blob decompression, relevant to a battery-carrying kit), and TEMP_REFERENCE/metakit is UNPATCHED upstream while KitCreator carries eight 8.x-era fixes. Self-mount shadowing verified live rather than inferred: inside a running tclkit [file type [info nameofexecutable]] is 'directory', so a kit cannot read or copy itself as a file and cannot be handed to sdx as -runtime (wrap.tcl LoadHeader is a plain file read). make.tcl:4995-5005 already works around this with _BUILDCOPY; recorded as a requirement to preserve. Container-agnostic - zipfs has the same shape via its /app anchor. src/buildsuites/suite_tcl86/patches/ captures the bin/sdx.kit delta into tracked form. bin/sdx.kit is tracked and is what make.tcl resolves for the 'kit' wrap path, but it is NOT stock sdx: unwrapping it and stock 2011-03-17 sdx gives 64 identical files except lib/app-sdx/wrap.tcl, whose entire difference is a two-line binary-mode read of tclkit.inf before stringfileinfo patches the PE version resource. That evidence previously existed only in gitignored scratch/ and TEMP_REFERENCE/ copies - one git clean from gone. Stock baseline, patched file and diff are all byte-exact (hashes in the README); the patch round-trips to the patched file byte for byte under 'patch --binary'. The stock baseline is kept in full because upstream (svn://svn.equi4.com/sdx/trunk) no longer exists. Both .tcl files are CRLF and must stay CRLF - vendored fidelity artifacts, exempt from the repo's LF-on-edit preference. Scope-limiting facts recorded rather than assumed: the patched path is DORMANT for present builds (fires only with -runtime + a .exe runtime + a tclkit.inf in the source .vfs, and no tclkit.inf exists in this repo), and the fix itself is UNVERIFIED - plausible as a CRLF-corruption fix but no reproducer was recorded with it. Confirming or retiring it is part of this goal's characterization work, alongside the bootstrap circularity noted in the goal (sdx.kit is itself a metakit starkit, so wrapping a suite-built 8.6 runtime currently needs a prebuilt third-party tclkit of exactly the kind G-101 exists to replace). Of the two proposed acceptance riders, this commit discharges the first (capture the patch before any sdx rebuild). The second stands: the end-to-end demonstration must wrap a SEPARATE COPY of the runtime so the shadowing path is exercised rather than accidentally avoided. A back-pointer to these findings was added to TEMP_REFERENCE/AGENTS.md so the survey is not repeated; that tree is VCS-ignored, so it is not part of this commit. Claude-Session: https://claude.ai/code/session_014UkdFjhuEdfCNDp4f8V6Xe Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
5 days ago |
|
|
f89bd58c31 |
G-100 achieved: suite_tcl86 dependency set (Tk 8.6, tklib, tcllib + tcllibc) and an 8.6 runtests census
Extends the 8.6 buildsuite with the remaining pieces punkshell's Tcl 8 testing
depends on, all built from source with the pinned zig 0.16.0 toolchain only.
Tk 8.6.17 (build_tk86/build_tk86.zig) is a RE-DERIVATION from the staged 8.6
win/makefile.vc + rules.vc, not a port of suite_tcl90's build_tk.zig:
- no generic/tkPkgConfig.c in 8.6 -> no CFG_* defines at all
- rules.vc TCL_MAJOR_VERSION==8 arm -> tk86t.dll + lib/tk8.6 (vs tcl9tk90.dll)
- @TK_WIN_VERSION@ substitutes $(DOTVERSION).0.0, not the tcl-style
<dotversion>.<releaselevel>.<patchlevel> formula
- 8.6 TKOBJS carries no tkIcu/tkImgListFormat/tkImgSVGnano/tkWinGDI/tkWinIco/
tkWinSysTray; XLIBOBJS is a first-class makefile macro here (the 9.0
derivation had to recover those files by hand)
USE_TCL_STUBS + USE_TCLOO_STUBS against libtclstub86.a is the stock rules.vc
arrangement and keeps the dll loadable by both suite shells. tkMain.c is
compiled twice per makefile.vc, the ansi copy forced with -UUNICODE/-U_UNICODE
(verified the pinned zig cc defines neither for x86_64-windows-gnu, so the 8.6
core's ANSI/TCHAR arrangement is matched exactly).
tklib 0.9 and tcllib 2.0 install via their own installer.tcl (batch, packages
only, explicit -pkg-path so the installer's tcl_pkgPath-derived default can
never write off-tree); tcllibc is built by critcl 3.3.1 driving zig cc (tracked
critcl_zig.config, target pinned win32-x86_64-zig - critcl otherwise probes PATH
and falls back to its builtin msvc target). critcl compiles against its own
bundled headers chosen by the driving shell's version, which is why one config
serves both generations.
New evidence tools, run on every build:
tools/tk_smoke.tcl maps a real toplevel with classic + themed widgets,
updates, then destroys it - a load-only check passes
even with no usable display
tools/accel_bench.tcl same payload through sha1's critcl and pure-Tcl
implementations with the digests compared:
4MB -> critcl 5.7ms vs pure-tcl 2736ms = 477x
Test tiers (G-107 policy pattern): test-tcllib/test-tklib on the record tier
inside test-libraries, plus an opt-in test-tk (winDialog/winMsgbox excluded by
default - their message-injection automation blocks on a human under a batch
shell). First censuses on tclsh86ts.exe 8.6.18:
thread 142 run / 0 failed GATE PASS
tklib 796 run / 0 failed record
tcllib 64259 run / 41 failed record (names in the summary artifact)
tclvfs 51 run / 4 failed GATE PASS after baseline extension
The tclvfs baseline grew vfsFtp-1.1..1.3: they sit behind an 'ftp' constraint
needing tcllib's ftp package - absent at the G-099 capture, satisfied now that
the suite installs tcllib - so they run and reach the retired ftp.tcl.tk, the
same external-service class already baselined for vfsUrl-1.2/2.1.
punkshell runtests census (both runs 2026-07-26, identical flags, default
single-process sequential - 8.6 has no tcl::process so -jobs re-convoys):
native Tcl 8.6.17 1003 total / 986 passed / 10 skipped / 7 failed
suite tclsh86ts 1003 total / 987 passed / 10 skipped / 6 failed
runtests_parity.tcl finds exactly ONE difference: punkcheck
concurrency_two_writers_no_corruption failed in the BASELINE run and passed on
the suite runtime - a full-suite-load flake (6/6 twice in isolation on both
runtimes). Zero suite-runtime-only failures. Tk-dependent suites ran unskipped
(repl consolebackends 3/3, including the tkconsole backend on the suite Tk).
Two defects fixed in passing:
- scrubTclEnv never cleared TCL<major>_<minor>_TM_PATH, so suite shells
silently preferred machine/repo tm modules over what the suite had just
installed (a repo-built sha1-2.0.4.tm shadowed tcllib's 2.0.5, md5 2.0.8
shadowed 2.0.9) - any census through such a shell measures the machine. The
scrub list now covers TCL8_0..8_7 + TCL9_0/9_1 in all three sites (per-step,
suite.tcl process-level, bootstrap nested build). suite_tcl90 has the same
exposure via TCL9_0_TM_PATH and is deliberately untouched here (out of this
goal's scope) - pointers recorded in G-108 and G-116.
- build.zig.zon's .fingerprint was hand-authored, so 'zig build' from the
tracked suite dir died with 'invalid fingerprint' - the no-tclsh bootstrap
flow could never have run. Corrected to zig's computed value (its low half
is a checksum of the package name); 'zig build stage' now verified.
Goal flipped to achieved 2026-07-26 and archived; reference sweep updated G-005,
G-101, G-105 and ARCHITECTURE.md, and the archive-time xref pair G-101 <-> G-116
(whose only bridges were the archived G-100/G-103) gained a direct Related
pointer. No project-version bump - arm's-length build tooling, not shipped shell
behaviour.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
|
5 days ago |