From f37d97140365705375bac46a7d1cb3e67d3ce2e5 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Fri, 31 Jul 2026 05:41:46 +1000 Subject: [PATCH] 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 --- goals/G-123-thirdparty-runtime-tiers.md | 49 +++++++++++++++++++ src/buildsuites/suite_tcl90/build905.zig | 23 ++++++--- .../suite_tcl90/tools/family_artifacts.tcl | 20 +++++--- .../suite_tcl90/tools/family_check.tcl | 10 ++-- 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/goals/G-123-thirdparty-runtime-tiers.md b/goals/G-123-thirdparty-runtime-tiers.md index de55f443..4008f4db 100644 --- a/goals/G-123-thirdparty-runtime-tiers.md +++ b/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. diff --git a/src/buildsuites/suite_tcl90/build905.zig b/src/buildsuites/suite_tcl90/build905.zig index f4d27938..4da7cfb6 100644 --- a/src/buildsuites/suite_tcl90/build905.zig +++ b/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 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) + toml metadata + sha1sums for the verified family kits -> /family/punkbin/"); const artifacts_outdir = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "family", "punkbin", "win32-x86_64" }), "\\", "/"); diff --git a/src/buildsuites/suite_tcl90/tools/family_artifacts.tcl b/src/buildsuites/suite_tcl90/tools/family_artifacts.tcl index 1b499256..7c41fc3d 100644 --- a/src/buildsuites/suite_tcl90/tools/family_artifacts.tcl +++ b/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)]" diff --git a/src/buildsuites/suite_tcl90/tools/family_check.tcl b/src/buildsuites/suite_tcl90/tools/family_check.tcl index 6beaeb9f..79eb7eec 100644 --- a/src/buildsuites/suite_tcl90/tools/family_check.tcl +++ b/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)"