Browse Source

G-162 proposed: bakelist input-freshness via content-digest kit stamps

New goal (user-approved wording): 'make.tcl bakelist' gains per-kit payload/
runtime freshness verdicts answering "would a rebake change this kit?" without
baking - punkkit-stamp.toml schema 2 records content digests of each kit's
assembly inputs (payload vfs manifests via the assembler's existing per-entry
CRCs, runtime artifact digest, resolved mapvfs declaration, bake schema) and
bakelist compares them against the current tree. Verdicts degrade per kit to
'n/a (<reason>)' (pre-digest stamp, unreadable container, mk4 driver
unavailable) without aborting the listing; zip kits read pure-Tcl via
punk::zip, mk4 kits only where a metakit driver loads. Context records the
existing deployed column's real (narrower) role: deploy-hop integrity for the
locked-exe trap. Related: G-131, G-158, G-023, G-147, G-137.

goals_lint clean; overlap survey (goals_xref paths + score) recorded in Notes.

Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 7 days ago
parent
commit
a7f090b550
  1. 4
      GOALS.md
  2. 69
      goals/G-162-bakelist-kit-freshness.md

4
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

69
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 (<reason>)' - 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/<kit>
against bin/<kit> - 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 (<reason>)' 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).
Loading…
Cancel
Save