make.tcl: dirty-src provenance gate for build/promotion commands (G-026 direction)
Build/promotion commands (project packages modules libs vfs vfslibs bin
bootsupport vfscommonupdate) now warn when src/ has uncommitted fossil/git
changes - artifacts built from dirty src have no committed provenance.
Warn-only by default; new -dirty-abort flag makes the check aborting.
With '<builtexe> src' available for evaluating uncommitted source directly,
building is the promotion step this treats it as.
- punkboot::utils 0.2.0: vcs_dirty_warnings gains optional scope arg so only
changes under a subpath (src) count; unscoped vendorupdate call unchanged.
- Warnings print with a plain column-0 PROVENANCE-WARNING: token (greppable
in redirected output) + ANSI colour, shared with vendorupdate's dirty
source-project check, and are recapped at end-of-run via a wrapped ::exit
so they survive scrolling chatty build output.
- Interactive terminal runs (stdin -inputmode probe, tcl 8.7+/9) get a 3s
ctrl-c grace countdown before a dirty build proceeds; piped/agent/CI runs
pay no delay.
- 'make.tcl check' reports src provenance status and what the build
commands would do.
- Guarded require: stale/missing punkboot::utils snapshot degrades the check
to a skip notice, but -dirty-abort then aborts rather than silently losing
the requested strictness.
Project 0.10.2 -> 0.10.3.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
@ -5,6 +5,11 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to
Entries are newest-first; one bullet per notable change. See the root `AGENTS.md`
"Project Versioning" section for the bump policy.
## [0.10.3] - 2026-07-11
- make.tcl build/promotion commands (`project`, `packages`, `modules`, `libs`, `vfs`, `vfslibs`, `bin`, `bootsupport`, `vfscommonupdate`) now warn when `src/` has uncommitted fossil/git changes — artifacts built from dirty src have no committed provenance (G-026 direction). Warn-only by default; a new `-dirty-abort` flag makes the check aborting. Dirt outside `src/` is ignored (`punkboot::utils::vcs_dirty_warnings` gained an optional scope argument, utils 0.2.0). With `<builtexe> src` / `<builtexe> src shell` available for evaluating uncommitted source directly, building is the promotion step the warning treats it as.
- Provenance warnings (dirty-src gate and vendorupdate's dirty source-project check) are presented with a plain column-0 `PROVENANCE-WARNING:` token for automated discovery in redirected output plus ANSI colour for humans, and are recapped at the very end of the run (via a wrapped `::exit`) so they survive scrolling chatty build output. Interactive terminal runs (Tcl 8.7+/9 stdin `-inputmode` probe) additionally get a 3-second ctrl-c grace countdown before a dirty build proceeds; piped/agent/CI runs pay no delay. `make.tcl check` now reports src provenance status and what the build/promotion commands would do.
## [0.10.2] - 2026-07-11
- punk::libunknown bumped 0.1 → 0.2.0 (file renamed `libunknown-0.2.0.tm`), retroactively versioning the register_all_tm and source_pkgindex additions and adopting full `major.minor.patch` form. Verified nothing requires it by exact version or filename: punk_main.tcl and punk::repl glob `libunknown-*.tm` picking the highest by vcompare (the dev copy now also outversions the stale bootsupport/project.vfs `0.1` copies deterministically), bootsupport's include_modules.config lists it by name only. The module header now carries a version-history block in lieu of a buildversion.txt, and `src/modules/AGENTS.md` documents the manual-versioning bump mechanics for agents (same Patch/Minor/Major rules as buildversion-tracked modules).
@ -64,6 +64,8 @@ Recovery after a wrong path guess:
- Use `tclsh src/make.tcl libs` to build just the library packages.
- Use `tclsh src/make.tcl packages` to build both modules and libraries.
- Use `tclsh src/make.tcl vendorupdate` to refresh vendormodules from config. It warns (non-fatal) for each source project whose fossil/git checkout is dirty - vendored artifacts built from a dirty tree have no committed provenance; commit in the source project to clear the warning (enforcement policy tracked by goal G-026).
- All build/promotion commands (`project`, `packages`, `modules`, `libs`, `vfs`, `vfslibs`, `bin`, `bootsupport`, `vfscommonupdate`) warn similarly when this project's own `src/` has uncommitted fossil/git changes (dirt outside `src/` is ignored). Warn-only by default; pass `-dirty-abort` to make the check aborting. For evaluating uncommitted source without a build, prefer `<builtexe> src` / `<builtexe> src shell`. The check is `punkboot::utils::vcs_dirty_warnings` (optional scope argument) loaded guardedly from bootsupport - if the snapshot is stale/missing the check degrades to a skip notice (but `-dirty-abort` then aborts rather than silently losing the requested strictness).
- Provenance warnings (dirty-src gate + vendorupdate source-project check) print with a plain column-0 `PROVENANCE-WARNING:` token (grep for it in captured build output) and are recapped at the end of the run via make.tcl's wrapped `::exit`. Interactive terminal runs get a 3-second ctrl-c grace countdown before a dirty build proceeds; piped/agent runs skip it. `tclsh src/make.tcl check` reports the current src provenance status and what the build commands would do.
- Use `tclsh src/make.tcl vfscommonupdate` to rebuild `_vfscommon.vfs`.
- Uncommitted `make.tcl`-generated outputs may be batched into one commit, regardless of how many `make.tcl` invocations produced them. This covers punkcheck-managed build outputs that are VCS-tracked: `src/bootsupport/`, `_vfscommon.vfs/modules` + `/lib`, and declared per-kit `*.vfs/lib_tcl<N>/<pkg>` subfolders. (Root `modules/`, `lib/`, `modules_tcl<N>/`, `lib_tcl<N>/` are gitignored and never committed.) Each module's old→new version rename is atomic; a regeneration reflects one build-output refresh, not independent hand-edits. This is a carve-out from generic "split aggressively" commit guidance for punkcheck-managed build outputs only — it does not cover user-curated VFS content (`_config/`, per-kit `*.vfs/` outside declared `lib_tcl<N>` subfolders, `_aside/`, `mkzipfix.vfs`, `_vfscommon.vfs/doc`), which commits separately per its own concerns.
- Use `punk make.tcl project` or `punk902z make.tcl project` inside Punk shell when building binaries through Punk.
set fchanges [string trim [exec {*}[auto_execok fossil] changes]]
} errM]} {
lappend warnings "WARNING: ${label}could not determine fossil state of source project at $fossilroot ($errM)"
} elseif {$fchanges ne ""} {
lappend warnings "WARNING: ${label}source project at $fossilroot has uncommitted fossil changes ([llength [split $fchanges \n]] file(s)) - artifacts built from a dirty tree have no committed provenance"
} else {
set flines [list]
foreach line [split $fchanges \n] {
set line [string trim $line]
if {$line eq ""} {continue}
if {$scopeabs ne ""} {
#fossil changes lines are '<STATUS> <path-relative-to-checkout-root>'
if {![regexp {^\S+\s+(.*)$} $line _ relfile]} {continue}
set normfile [file normalize [file join $fossilroot $relfile]]
if {$normfile ne $scopeabs && ![string match "${scopeabs}/*" $normfile]} {continue}
}
lappend flines $line
}
if {[llength $flines]} {
lappend warnings "WARNING: ${label}source project at $fossilroot has uncommitted fossil changes${scopedesc} ([llength $flines] file(s)) - artifacts built from a dirty tree have no committed provenance"
}
}
cd $original_cwd
}
if {$gitroot ne "" && ![dict exists $checkedroots git,$gitroot] && [llength [auto_execok git]]} {
dict set checkedroots git,$gitroot 1
if {$gitroot ne "" && ![dict exists $checkedroots git,$gitroot,$scope] && [llength [auto_execok git]]} {
dict set checkedroots git,$gitroot,$scope 1
set gitpathargs [list]
if {$scopeabs ne ""} {
set gitpathargs [list -- $scopeabs]
}
if {[catch {
set gchanges [string trim [exec {*}[auto_execok git] -C $gitroot status --porcelain]]
set gchanges [string trim [exec {*}[auto_execok git] -C $gitroot status --porcelain {*}$gitpathargs]]
} errM]} {
lappend warnings "WARNING: ${label}could not determine git state of source project at $gitroot ($errM)"
} elseif {$gchanges ne ""} {
lappend warnings "WARNING: ${label}source project at $gitroot has uncommitted git changes ([llength [split $gchanges \n]] file(s)) - artifacts built from a dirty tree have no committed provenance"
lappend warnings "WARNING: ${label}source project at $gitroot has uncommitted git changes${scopedesc} ([llength [split $gchanges \n]] file(s)) - artifacts built from a dirty tree have no committed provenance"
#0.2.0 - vcs_dirty_warnings: optional scope arg limiting which uncommitted changes count (e.g scope src for make.tcl build/promotion dirty-src gate)
#0.1.1 - added vcs_dirty_warnings (dirty fossil/git checkout provenance warnings; used by make.tcl vendorupdate, shared with bootsupport update per goal G-026)