# punkbin — punkshell binary artifact repository ## Purpose Pinned binary artifacts for the punkshell project (github/gitea: jn/shellspy - the project is punkshell; "shellspy" is a legacy repo name): per-platform Tcl runtime executables used as the basis for building punkshell kits/zipkits, plus selected build tools. This repository exists so that build and test environments can retrieve exact, checksummed runtime binaries instead of depending on moving upstream releases (e.g. beta runtimes such as tclsfe-x64.exe from github.com/apnadkarni/tcl-sfe) or on binaries that exist only on one developer machine. This artifact repository is specific to the punkshell project. ## Ownership - Owned by the punkshell project maintainer. - Agents may add artifacts and update checksums when the punkshell project work calls for it (e.g. preserving a runtime that punkshell tests depend on) - report additions in the completion summary. - Agents must not modify or delete existing binaries; superseding a runtime means adding the new file, not overwriting the old one. ## Local Contracts - Layout: one folder per platform (`win32-x86_64/`, `linux-x86_64/`, `linux-arm/`, `macosx/`, `freebsd-arm64/`, ...), optional `tools/` subfolders for build tooling (e.g. zig archives). `src/` holds maintenance scripts for this repository itself. Platform folder names follow the punkshell canonical platform names (punk::platform module / `help platforms` in the punk shell). - `lib/` is the LIBRARY artifact tier (shellspy G-138), distinct from the runtime platform folders: `lib/allplatforms/` for platform-neutral packages (pure-Tcl), `lib//` per platform for binary packages, each target subfolder with its own `sha1sums.txt`. `lib/` never appears in `platforms.txt` (runtime folders only). See "Library artifacts - lib tier (schema v2)" below. - `platforms.txt` at the repo root lists the platform folders this repo serves (one name per line; `#` comments and blanks ignored) - the discovery manifest for raw-file consumers that have no directory-listing capability (`punk-runtime.cmd platforms -remote`, and third-party mirrors using the same layout should carry the same file). Regenerated by `src/build_sha1sums.tcl`. - `defaults.txt` at the repo root is the CURATED per-platform recommended default fetch runtime (` ` per line; `#` comments/blanks ignored) consulted by `punk-runtime.cmd fetch` when no runtime name is given. Hand-edited, never generated - it records a release DECISION. The release process: publish the artifact (add, `git add`, run `src/build_sha1sums.tcl`), then point the platform's `defaults.txt` line at it IN THE SAME CHANGE-SET - the script validates entries (warns on unknown platforms or missing artifact files) so drift between the halves is caught. A platform with no line has no recommendation (punk-runtime tells the user to name a runtime explicitly). Mirrors may curate their own recommendations. - Every platform folder (and tool subfolder) carries a `sha1sums.txt` with one ` *` line per artifact (binary-mode marker `*`). - `sha1sums.txt` (and `platforms.txt`) are regenerated with `tclsh src/build_sha1sums.tcl` from the repo root. The script only sums git-tracked files - `git add` a new artifact BEFORE running it. It reports NEW/SAME/CHANGED per file; a CHANGED line for an existing artifact is a red flag (artifacts are immutable - investigate, don't commit). - Binaries are deliberately committed here - this repo is the exception to the punkshell source repo's no-committed-binaries direction (shellspy G-004): the source repo points at this one (G-006 retrieval direction) instead of carrying binaries itself. - Runtime expectations (see README.md): self-contained Tcl interpreters usable as kit bases; punk runtimes load Tk as an extension (no separate Tk runtime). Runtimes with statically-linked packages (e.g. tclsfe-x64.exe: Thread, twapi, sqlite3, tdbc) are supported by punkshell boot as of shellspy G-058. ## Artifact metadata records (schema v1) Family runtime artifacts (shellspy G-103/G-117) are metadata-carrying in TWO copies: - SIDECAR: `.toml` beside the artifact, listed in `sha1sums.txt`. The sidecar + sha1sums are the INTEGRITY AUTHORITY. - EMBEDDED: the same record minus the finished-binary facts, at `punkbin-artifact.toml` inside the artifact's attached (exe-appended) zip image - written at kit-family staging BEFORE wrapping and hashing (embed-then-hash: the embedded copy can never contain its own sha1). It makes a runtime separated from its sidecar (out-of-band copy, rename) self-describing: `punk-runtime info ` reads it WITHOUT executing the target (zip central-directory read of the exe-appended archive - .NET in the ps1 payload, unzip in the bash payload; a cooperative probe piping a reader script into the EXECUTED target is the documented fallback for hosts with no zip reader, with the obvious caveat about running untrusted binaries) and flags embedded-vs-sidecar disagreements. The record survives punkshell's make.tcl kit wrapping (the kit vfs overlays the image without clearing it), so wrapped kits inherit their runtime's record (shellspy G-025 treats it as the runtime-provenance layer of kit self-reporting). Field semantics (v1; `schema = 1` at the top of both copies): - `schema` - record format version. Absent = pre-v1 (r1-era records; consumers parse them tolerantly). - `[artifact]` `name`/`class`/`variant`/`working_name`/`revision`/`target` - the G-103 identity: immutable `-r` artifact name, `runtime` class, family variant (plain/punk/punk-bi), the working name `use` materializes to, assembly revision, punkbin platform target. - `sha1`/`size`/`built` - SIDECAR-ONLY finished-binary facts. - `build_id` - offline correlation key re-joining a renamed stray copy to its record; IDENTICAL in embedded and sidecar copies. A deterministic uuid-shaped digest of stable identity inputs (artifact name, toolchain/optimize, patchlevel, per-member source checkout uuids) - a correlation key, NOT an integrity key (sha1sums is). - `origin` - the canonical artifact repo this artifact was BUILT FOR (suite option `-Doriginurl`, default this repo's url) - NOT necessarily where it is hosted; mirrors preserve it, so an artifact found on a third-party repo still declares its home. Where an artifact actually lives is the hosting repo's own business. - `packager` - DECLARED builder identity (`-Dpackager` > env `PUNKBIN_PACKAGER` > the building checkout's git identity > `"unrecorded"`). Declarative, not proof: the verification layer is signing - per-artifact `.minisig` sidecars (this repo's existing minisign practice for zig tool archives) are the natural complement, deliberately outside the metadata file (a signature cannot live inside what it signs). - `project`/`project_url` - what a stray artifact belongs to beyond its origin repo (`-Dprojecturl`; `unrecorded` until a canonical url is chosen). - `license` - summary for the distributed artifact (`TCL` for family runtimes); component license texts ride inside the attached image. - `build_host_platform` - platform the artifact was built ON (meaningful once cross-builds exist; equals `target` today). - `[runtime]` `tcl_patchlevel`, `piperepl`/`piperepl_default`/`piperepl_opt_out`, `attached_batteries` - probed-verifiable runtime facts (the suite's family_check asserts them against the actual binary). - `[provenance]` `suite`/`toolchain`/`optimize`/`*_checkout` - build provenance (fossil checkout uuids per component). - `[tests]` - per-suite test-gate result lines (sidecar only; from the G-107 evidence summaries). Records carry `#` comment lines documenting the non-obvious fields; consumers are line-based and ignore comments and unknown fields by construction - new fields (e.g. the planned tls battery fields, shellspy G-116) extend v1 rather than fork it. Emission/verification tooling lives in shellspy `src/buildsuites/suite_tcl90` (`build905.zig` staging embed, `tools/family_artifacts.tcl` emission - the sidecar derives its identity fields from the embedded copy, `tools/family_check.tcl` embedded-record probe). ## Library artifacts - lib tier (schema v2) The `lib/` tier (shellspy G-138) carries suite-built LIBRARY packages as immutable `-r` zips of installed-shape package folders: `lib/allplatforms/` for platform-neutral packages (pure-Tcl tcllib), `lib//` for per-platform binary packages (tcllibc critcl accelerators). Consumption (shellspy G-139) materializes them into the punkshell repo's untracked `bin/packages//` input tier. - Naming: `--r.zip` (e.g. `tcllib2.0-tcl9-r1.zip`, `tcllibc-tcl8-r1.zip`). The GENERATION tag is part of artifact identity, not decoration: both Tcl generations install identically-named package folders (tcllib2.0, tcllibc) with genuinely different bytes (binary packages link per-generation; installer output differs). `-r` revisions are immutable exactly as in the runtime tier. - Each zip contains the package folder in installed pkgIndex.tcl shape plus the EMBEDDED record at `/punkbin-artifact.toml` (package root, beside pkgIndex.tcl - inert to package loading), written before zipping (embed-then-hash: `sha1`/`size`/`built` remain SIDECAR-ONLY). Sidecar `.toml` + per-target `sha1sums.txt` are the integrity authority, exactly as for runtimes. - Record shape (`schema = 2`): the v1 identity set plus, in `[artifact]`, `class = "library"` with `package`/`package_version`/`folder`/`tcl_generation` (replacing the runtime tier's variant/working_name); a `[library]` table with `driving_tcl_patchlevel` (patchlevel of the suite-built shell that ran the installer/critcl - the generation witness, not a runtime requirement); and in `[provenance]`, `class = "suite-built"` (schema-v2 build-origin class: suite-built | third-party | local - the shellspy G-123 lineage), the source checkout uuids (`tcllib_checkout`, `critcl_checkout`) and `critcl` (version declared by the package's own critcl teapot.txt, accelerator packages only). - Schema v2 is a SUPERSET of v1: line-based v1 consumers ignore the new fields by construction. Ordering caveat for whole-text single-key scanners: `[artifact] class` is the FIRST `class =` line in every record by construction; a consumer that wants `[provenance] class` must parse tables. - Determinism/publish discipline: zips are punkzip-assembled (sorted members, staged mtimes synced) so re-emission over an unchanged install is byte-identical - but the dlls INSIDE are not bit-reproducible across zig rebuilds, so revisions bump only on deliberate publish, never per rebuild. - md5c is deliberately NOT published: tcllib's md5 accelerator resolution prefers tcllibc (modules/md5/md5x.tcl), which bundles the md5 accelerator. - Emission tooling: shellspy `src/buildsuites/suite_tcl90` + `suite_tcl86` `tools/library_artifacts.tcl` (`library-artifacts` step in both recipes; suite READMEs document the mechanism). Publication remains a deliberate user step: copy `out/library/punkbin/lib/*` into `lib/`, `git add`, run `tclsh src/build_sha1sums.tcl` (it processes each `lib//` subfolder), commit. Minisign posture unchanged: sha1sums are transport integrity; per-artifact `.minisig` sidecars remain the anticipated verification layer. ## Work Guidance - Adding a runtime: copy it into the platform folder, `git add` it, run `tclsh src/build_sha1sums.tcl`, verify the NEW line's checksum, commit with a message recording provenance (upstream URL/version/build source). - Consumers: the punkshell project retrieves runtimes into its `bin/runtime//` via `bin/punk-runtime.cmd` or manual copy; punkshell's `src/runtime/mapvfs.config` maps runtimes to vfs payloads. - Do not push on an agent's initiative - the remote is the project's upstream artifact store; the maintainer controls what is published. ## Verification - `tclsh src/build_sha1sums.tcl` reports SAME for every pre-existing artifact and NEW only for intended additions. ## Child DOX Index (None - flat platform folders with artifacts, checksums and README.md; `src/` is a single maintenance script.)