Browse Source

G-123 increment 1: runtime artifact records to schema v2 (provenance class)

family_artifacts.tcl and the build905.zig embedded-record literal move
schema 1 -> 2, adding [provenance] class = "suite-built" with the
lib-tier ordering-caveat comment (G-138 lineage - [artifact] class stays
the first 'class =' line; whole-text single-key scanners see that one).
The embedded-vs-sidecar consistency gate expects v2, and
family_check.tcl asserts embed_schema 2 plus the literal
'class = "suite-built"' line (its flat scanner would see [artifact]
class first, per the caveat). Verified: zig ast-check clean, both tools
parse; functional family-build proof is the next step - published v1
records stay valid pre-v2 records, v2 appears from the next family
revision.

Companion punkbin commit 1f10390 (local, unpushed): 12 retroactive
schema-v2 sidecars covering every pre-family runtime artifact across
the five tiers, evidence-based classes (binary markers, punkbin git
history, live kit probes), additive-only (artifact bytes + sha1 rows
unchanged), AGENTS.md runtime-v2 section + README refresh.

Goal Progress records the baseline survey findings (tier argument
already present on fetch/list/use; bash 'info -platform' defect; no
client-side server-trust gate; ps1 Scope path correction pending user
approval).

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 2 days ago
parent
commit
f37d971403
  1. 49
      goals/G-123-thirdparty-runtime-tiers.md
  2. 23
      src/buildsuites/suite_tcl90/build905.zig
  3. 20
      src/buildsuites/suite_tcl90/tools/family_artifacts.tcl
  4. 10
      src/buildsuites/suite_tcl90/tools/family_check.tcl

49
goals/G-123-thirdparty-runtime-tiers.md

@ -140,3 +140,52 @@ see goals/archive/G-058-static-runtime-packages.md).
autodetection widens which served runtimes are kit-wrappable, and its
zipfs specimens live in the bin/runtime/win32-ix86 tier of third-party
tclkits this goal's provenance backfill covers.
## Progress
- 2026-07-31 baseline survey (user-directed activation same day). Findings
load-bearing for the remaining work: the explicit -platform tier argument
ALREADY exists on fetch/list/use in both payloads (G-105/G-122 era) with
tier-scoped freshness verdicts - the real client gaps are (a) bash
'info -platform' advertised in both help texts but non-functional ('info'
missing from the option-scan action list at punk-runtime.bash:111; the ps1
twin handles it), (b) provenance DISPLAY (list -remote notes column +
info), and (c) consent: PUNKBIN_URL is honoured silently in both payloads -
no server-trust gate exists client-side (the -trust-server precedent is
make.tcl libfetch only; three independent copies of the canonical origin
URL exist: punk-runtime.bash:14, punk-runtime.ps1:697, make.tcl:5314).
SCOPE CORRECTION PENDING USER APPROVAL (contract edit): the ps1 payload
lives at src/scriptapps/bin/punk-runtime.ps1, not the Scope-recorded
src/scriptapps/punk-runtime.ps1.
- 2026-07-31 increment 1: runtime schema v2 + retroactive sidecars.
- Emission (this repo): family_artifacts.tcl + the build905.zig embedded
literal moved schema 1 -> 2 with [provenance] class = "suite-built" and
the lib-tier ordering-caveat comment (G-138 lineage); the
embedded-vs-sidecar consistency gate now expects v2; family_check.tcl
asserts embed_schema 2 AND pins the literal 'class = "suite-built"'
line (its flat rfield scan would see [artifact] class first - the
documented caveat, pinned as designed). Verified so far: zig ast-check
clean, both tools parse (fail-fast option errors); the functional
family-build proof (kit-family + kit-family-artifacts steps under
suite.tcl) is the next verification step - v2 records appear in
artifacts only from the next published family revision.
- punkbin side (git 1f10390, LOCAL ONLY - not pushed; publication stays
the maintainer's call): 12 retroactive schema-v2 sidecars across all
five runtime tiers - every pre-family artifact now carries
machine-readable build origin ([provenance] class third-party|local
plus builder/source_url/upstream_ref/retrieved, "unrecorded" where
unknown - never guessed; evidence basis in adjacent comments: binary
markers (Bawt/obermeier/MinGW-W64/MSYS2 GCC/Metakit), punkbin git
history, live probes of the win32 kits for tcl_patchlevel/container).
Per-tier sha1sums gained exactly the 12 toml rows (artifact rows
byte-identical, order-only shifts); AGENTS.md gained the "Runtime
artifacts - schema v2 + retroactive sidecars" section (field-subset +
additive contract + never-guess posture); README default r1 -> r2 and
platform list refreshed.
- Classification judgement calls FOR MAINTAINER REVIEW before push:
tclkit86bi and the four non-windows tclkits recorded third-party (BAWT
distribution attribution from binary markers - they could equally be
maintainer-run BAWT builds); tclkit902/tclsh902z* recorded local (the
"built using bawt" 9f13f97 commit wording); tclsh901k/t local
(interim/test-runtime commit wording). Every such value carries its
basis comment in the record, so flipping a class is a one-line edit.

23
src/buildsuites/suite_tcl90/build905.zig

@ -2432,7 +2432,7 @@ pub fn build(b: *std.Build) !void {
//change: tclvfs forTcl9/1.5.0) emit as r2 until r2 is itself published
//and superseded. Bump this default whenever the current rev publishes.
const familyrev = b.option(u32, "familyrev", "assembly revision N for the -r<N> family artifact names (kit-family-artifacts; default 2 - r1 published 2026-07-22)") orelse 2;
//G-117 schema v1 identity options. origin = canonical artifact repo the
//G-117 schema identity options (v2 as of G-123). origin = canonical artifact repo the
//artifacts are BUILT FOR (not necessarily where they end up hosted -
//mirrors preserve it). packager = declared identity, resolution chain
//-Dpackager > env PUNKBIN_PACKAGER > building checkout's git identity >
@ -2482,7 +2482,8 @@ pub fn build(b: *std.Build) !void {
const uuid_tcllib = common.manifestUuid(b, "../tcllib");
const uuid_tklib = common.manifestUuid(b, "../tklib");
//G-117: per-member EMBEDDED artifact record (schema v1), staged into each
//G-117: per-member EMBEDDED artifact record (schema v2 as of G-123:
//[provenance] class = "suite-built" added to the v1 shape), staged into each
//member's payload tree as base/punkbin-artifact.toml (namespaced so a
//future G-025 kit-stamp file can coexist; the record survives make.tcl
//kit wrapping, which overlays without clearing). Finished-binary facts
@ -2518,11 +2519,12 @@ pub fn build(b: *std.Build) !void {
else
b.fmt("tcl_checkout = \"{s}\"\nthread_checkout = \"{s}\"\ntclvfs_checkout = \"{s}\"\ntcllib_checkout = \"{s}\"", .{ uuid_tcl, uuid_thread, uuid_tclvfs, uuid_tcllib });
family_records[ki] = b.fmt(
\\#punkshell runtime artifact metadata - EMBEDDED copy (G-117 schema v1),
\\#written at kit-family staging. Finished-binary facts (sha1, size, built)
\\#live only in the sidecar toml + sha1sums.txt, which remain the integrity
\\#authority; this copy makes a stray or renamed runtime self-describing.
\\schema = 1
\\#punkshell runtime artifact metadata - EMBEDDED copy (schema v2, class
\\#"runtime"), written at kit-family staging. Finished-binary facts (sha1,
\\#size, built) live only in the sidecar toml + sha1sums.txt, which remain
\\#the integrity authority; this copy makes a stray or renamed runtime
\\#self-describing.
\\schema = 2
\\
\\[artifact]
\\name = "{s}"
@ -2554,6 +2556,11 @@ pub fn build(b: *std.Build) !void {
\\attached_batteries = {s}
\\
\\[provenance]
\\#class: build-origin class (schema v2): suite-built | third-party | local.
\\#NOTE for line-based consumers: '[artifact] class' above is the first
\\#'class =' line in the record by construction - whole-text single-key
\\#scans see that one.
\\class = "suite-built"
\\suite = "suite_tcl90"
\\toolchain = "zig {s}"
\\optimize = "{s}"
@ -2637,7 +2644,7 @@ pub fn build(b: *std.Build) !void {
//family runtime executes real tooling from its attached batteries.
//Depends on the checks: only verified kits get artifact records.
//Publication to the real punkbin repo stays a deliberate user step.
//(familyrev + the schema v1 identity options and checkout uuids are
//(familyrev + the schema identity options and checkout uuids are
//declared above with the family staging - the embedded records need them)
const family_artifacts_step = b.step("kit-family-artifacts", "emit punkbin-layout artifact copies (-r<N>) + toml metadata + sha1sums for the verified family kits -> <prefix>/family/punkbin/<target>");
const artifacts_outdir = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "family", "punkbin", "win32-x86_64" }), "\\", "/");

20
src/buildsuites/suite_tcl90/tools/family_artifacts.tcl

@ -1,4 +1,5 @@
#family_artifacts.tcl (G-103, schema v1 per G-117): emit punkbin-layout artifact
#family_artifacts.tcl (G-103; schema v2 per G-117 lineage + G-123 provenance
#class): emit punkbin-layout artifact
#copies + per-artifact toml metadata + sha1sums for the verified runtime kit
#family members. The sidecar's identity fields (schema, build_id, origin,
#packager, project, license, build_host_platform) are DERIVED from the record
@ -128,7 +129,7 @@ foreach {variant kitpath} $opt(-kits) {
#build_id by construction; every emission inherently verifies the embed exists
#and matches this invocation (stale-staging tripwire).
set embedded [read_embedded $kitpath]
foreach {ekey expect} [list schema 1 name $artifact variant $variant working_name $working revision $opt(-rev) target $opt(-target) tcl_patchlevel $opt(-tclpatch)] {
foreach {ekey expect} [list schema 2 name $artifact variant $variant working_name $working revision $opt(-rev) target $opt(-target) tcl_patchlevel $opt(-tclpatch)] {
set got [record_field $embedded $ekey]
if {$got ne $expect} {fail "$artifact embedded record mismatch: $ekey = '$got', expected '$expect' (stale staging?)"}
}
@ -145,11 +146,12 @@ foreach {variant kitpath} $opt(-kits) {
}
set m {}
lappend m "#punkshell runtime artifact metadata (G-117 schema v1) - generated by family_artifacts.tcl"
lappend m "#sidecar copy: the embedded record carried inside the artifact's attached image"
lappend m "#(punkbin-artifact.toml) plus the finished-binary facts (sha1, size, built)."
lappend m "#The sidecar + sha1sums.txt remain the integrity authority."
lappend m "schema = 1"
lappend m "#punkshell runtime artifact metadata (schema v2, class \"runtime\") - generated by"
lappend m "#family_artifacts.tcl. Sidecar copy: the embedded record carried inside the"
lappend m "#artifact's attached image (punkbin-artifact.toml) plus the finished-binary"
lappend m "#facts (sha1, size, built). The sidecar + sha1sums.txt remain the integrity"
lappend m "#authority."
lappend m "schema = 2"
lappend m ""
lappend m "\[artifact\]"
lappend m "name = [toml_str $artifact]"
@ -189,6 +191,10 @@ foreach {variant kitpath} $opt(-kits) {
lappend m $batteries_line
lappend m ""
lappend m "\[provenance\]"
lappend m "#class: build-origin class (schema v2): suite-built | third-party | local."
lappend m "#NOTE for line-based consumers: '\[artifact\] class' above is the first 'class ='"
lappend m "#line in the record by construction - whole-text single-key scans see that one."
lappend m "class = \"suite-built\""
lappend m "suite = [toml_str $opt(-suite)]"
lappend m "toolchain = [toml_str "zig $opt(-zig)"]"
lappend m "optimize = [toml_str $opt(-optimize)]"

10
src/buildsuites/suite_tcl90/tools/family_check.tcl

@ -207,7 +207,7 @@ if {$opt(-variant) eq "plain"} {
note "piperepl OK ($opt(-variant)): active by default (reopened published 0), disabled via TCLSH_PIPEREPL=0"
}
#-- probe: embedded artifact record (G-117 schema v1) -------------------------
#-- probe: embedded artifact record (schema v2 - G-117 lineage + G-123 class) -
set embed_script {
proc out {k v} {puts [list CHECK $k $v]}
proc rfield {rec k} {
@ -233,11 +233,15 @@ set embed_script {
set line [string trim $line]
if {[string match "attached_batteries*" $line]} {out embed_batteries $line; break}
}
#G-123 schema v2: the flat rfield scan would see [artifact] class first (the
#documented ordering caveat), so pin the [provenance] class as a literal line.
out embed_provclass [expr {[string first {class = "suite-built"} $rec] >= 0}]
exit 0
}
set d [checks [probe embedrecord $embed_script]]
asserteq $d embed_exists 1 "embedded record (G-117)"
asserteq $d embed_schema 1 "embedded record"
asserteq $d embed_schema 2 "embedded record"
asserteq $d embed_provclass 1 "embedded record (\[provenance\] class = suite-built - G-123 schema v2)"
asserteq $d embed_variant $opt(-variant) "embedded record"
asserteq $d embed_tcl_patchlevel $opt(-expectpatch) "embedded record"
asserteq $d embed_working_name $kitname "embedded record"
@ -261,7 +265,7 @@ if {$opt(-variant) eq "punk-bi"} {lappend expected_batteries Tk $opt(-tk) tklib
foreach {bn bv} $expected_batteries {
if {[string first "\"$bn $bv\"" $bl] < 0} {fail "embedded record: attached_batteries missing '$bn $bv' (line: $bl)"}
}
note "embedded record OK: schema 1, name [dict get $d embed_name], build_id [dict get $d embed_build_id]"
note "embedded record OK: schema 2 (provenance class suite-built), name [dict get $d embed_name], build_id [dict get $d embed_build_id]"
file delete -force $scratch
puts "family_check OK: $opt(-variant) $kitname self-contained (scratch-dir probes, scrubbed env)"

Loading…
Cancel
Save