diff --git a/GOALS.md b/GOALS.md index 4bde8849..02d0b8a9 100644 --- a/GOALS.md +++ b/GOALS.md @@ -408,3 +408,7 @@ Detail: goals/G-158-punk86-kit-parity.md Scope: src/modules/punk/tcltestrun-999999.0a1.0.tm (parse_testrun failure-banner state machine); src/tests/runner/ (parser characterization suite - synthetic captured-output + end-to-end failing-fixture coverage); src/tests/AGENTS.md (single-line-description contract note relaxed to style guidance once tolerated) Detail: goals/G-161-tcltestrun-multiline-banner.md +### G-162 [proposed] bakelist input-freshness: content-digest kit stamps and would-a-rebake-differ verdicts +Scope: src/make.tcl (bake stamp writer, bakelist report, digest/cache helpers); src/modules/punk/buildinfo-999999.0a1.0.tm (surface new stamp fields); src/vfs/ (payload trees as digest inputs); src/runtime/ (runtime artifacts and mapvfs.toml as consumed inputs); src/tests/shell/testsuites/punkexe/ (freshness pin) +Detail: goals/G-162-bakelist-kit-freshness.md + diff --git a/goals/G-162-bakelist-kit-freshness.md b/goals/G-162-bakelist-kit-freshness.md new file mode 100644 index 00000000..fdb2f28a --- /dev/null +++ b/goals/G-162-bakelist-kit-freshness.md @@ -0,0 +1,69 @@ +# G-162 bakelist input-freshness: content-digest kit stamps and would-a-rebake-differ verdicts + +Status: proposed +Scope: src/make.tcl (bake stamp writer, bakelist report, digest/cache helpers); src/modules/punk/buildinfo-999999.0a1.0.tm (surface new stamp fields); src/vfs/ (payload trees as digest inputs); src/runtime/ (runtime artifacts and mapvfs.toml as consumed inputs); src/tests/shell/testsuites/punkexe/ (freshness pin) +Goal: 'make.tcl bakelist' answers "would a rebake change this kit?" without baking: the bake records content digests of each kit's assembly inputs (payload vfs trees, runtime artifact, resolved mapvfs declaration, bake/assembler schema) in the deterministic punkkit-stamp.toml, and bakelist compares those against the current tree to report a per-kit input-freshness verdict (payload and runtime) alongside the existing deploy-state column - so a pulled or locally-promoted change to any input surfaces as 'stale' before anyone bakes. +Acceptance: on a checkout where payload content consumed by a kit changed since that kit's last bake (e.g. one file modified under src/vfs/_vfscommon.vfs), 'make.tcl bakelist' reports that kit's payload verdict as stale without performing a bake, and reports current after a rebake; a runtime-store artifact differing from the stamped runtime digest is reported stale on the same terms; verdicts degrade per kit to 'n/a ()' - no deployed copy, pre-digest stamp schema, unreadable container, container driver unavailable - and a single unreadable kit never aborts or blanks the rest of the listing; zip kits are read pure-Tcl (punk::zip, no mount) on all supported build tclsh runtimes, mk4 kits are read when a metakit driver is loadable in the build interp and report n/a otherwise; stamps stay deterministic (identical inputs yield byte-identical stamp content across rebakes); a punkexe pin covers stale-detect, rebake-to-current and n/a degradation for at least one zip kit. + +## Context + +The existing bakelist 'deployed' column (G-121, archived) byte-compares src/_bake/ +against bin/ - a deploy-hop integrity check whose real target is the locked-exe +trap (bake exits 0 but the bin copy is skipped while a running shell holds the exe). +It says nothing about whether the bake product itself is stale relative to the tree: +after a git pull or a local vfscommonupdate, nothing reports that a rebake would +produce a different kit (user question 2026-08-03). + +The inputs are already well-defined and mostly fingerprinted: mapvfs.toml declares each +kit's vfs set and runtime (G-024/G-115, archived); the zip assembler computes a CRC32 +for every payload entry during assembly, so a payload digest (hash over the sorted +{relpath size crc} manifest) is nearly free at bake time; runtime artifacts carry +sha1/size in their G-117 sidecars (archived); punkkit-stamp.toml (G-025, archived) is +the deterministic in-kit stamp seam and punk::buildinfo already reads it (its +live_vs_stamp verdict is project_version-granular only). Bake-side determinism work +(G-031, archived) deliberately keeps time facts out of payloads. + +Comparison must be manifest/digest-based, not whole-file byte comparison: zip entries +carry source mtimes, so a rebake after a pull can differ byte-wise even with identical +content. Current-side digest cost is a walk+CRC of the consumed vfs trees (sub-second +cold; a {path size mtime}->digest cache brings the warm path to milliseconds, computed +once per vfs and shared across kits). + +## Approach + +- punkkit-stamp.toml schema 2: add per-input digests (one per consumed vfs tree, + runtime artifact digest from/alongside the G-117 sidecar, resolved mapvfs declaration + digest, bake/assembler schema version). No volatile fields (determinism preserved). +- bakelist: compute current-side digests with a warm cache; read the deployed kit's + stamp per container type - zip via punk::zip central-directory member extraction + (pure Tcl, no zipfs mount, works on all build tclshs), mk4 via mk4vfs/Mk4tcl only + when loadable; anything else (or failure at any step) degrades that kit's verdict to + 'n/a ()' without affecting other rows. +- New column semantics: payload current|stale|n/a, runtime current|stale|n/a; the + existing deployed column is unchanged. +- Out of scope (possible follow-ons): upstream pipeline-hop verdicts (mint-pending, + promotion-pending - derivable from punkcheck records); a -deep dry-run-assembly + oracle for assembler-behaviour changes (the stamped bake schema version covers the + common case); punk::buildinfo content-granular live-vs-source verdict (this goal + only surfaces the new stamp fields in its report). + +## Notes + +- Related: G-131 (one runtime, either payload - container autodetection) - shares the + zip/mk4 container axis; the stamp reader's per-container dispatch should align with + its detection conventions. +- Related: G-158 (punk86-kit parity on the suite-built mk4 head) - mk4 kits are the + live exercise of the driver-unavailable n/a path. +- Related: G-023 (version-named punk binaries) - sibling surface: both shape bakelist + rows and bin/ naming; no dependency either direction. +- Related: G-147 (libfetch revision check) - sibling read-only freshness-report + pattern (server revisions for lib artifacts vs local input digests for kits). +- Related: G-137 (kit version resources via punkres) - sibling bake-time kit-stamping + surface at the same make.tcl seam; its PE-resource stamping mutates the exe prefix + after assembly, which is compatible with this goal's determinism claim (stamp + content only, not whole-kit bytes). +- Overlap survey 2026-08-03: goals_xref paths src/make.tcl + buildinfo + src/runtime + + src/vfs, plus score G-162 unlinked review; live intersections named above. + Judged non-overlapping for this goal's mechanism: G-005/G-006/G-141 + (runtime provisioning) and G-065 (declarative vendoring - a producer of payload + changes this goal would report, no mechanism overlap).