5.3 KiB
G-125 A kit that cannot boot is not deployed
Status: proposed Scope: src/make.tcl (kit extraction outcome handling, deploy step gating, the no-extraction BUILD-WARNING as the current behaviour being replaced); src/tests/shell/testsuites/punkexe/ (characterization of the gate); src/AGENTS.md (bake failure-mode documentation) Goal: a bake that could not lift a runtime's own payload (its tcl_library) into the kit fails that kit instead of building and deploying an artifact that cannot boot - so the worst outcome of a missing extraction capability is a red kit, never a silently replaced working executable. Acceptance: when extraction from the source runtime yields nothing and the kit's .vfs does not itself supply a bootable tcl library, the kit is recorded in FAILED KITS with a reason naming the cause and NEITHER src/_build nor bin receives a new artifact - the previously deployed kit is left untouched, verified by mtime and byte comparison across such a run; a kit whose .vfs legitimately supplies its own tcl library still builds and deploys, so the gate tests for the boot precondition rather than for the extraction step having run; the check is cheap enough to run on every kit and executes no artifact; the condition and its remedy are documented in src/AGENTS.md; existing punkexe suites pass unchanged and the gate itself is characterized.
Context
The kit machinery already knows when it failed to extract anything from a source runtime.
Under G-122 (achieved - see goals/archive/G-122-host-target-platform-split.md) that
notice was promoted from an inline stderr block to a recapped BUILD-WARNING: naming the
kit and what was tried - but the build still proceeds, assembles an artifact, DELETES the
deployed kit and copies the new one over it. The pre-deploy process sweep will even close
running instances of the kit first.
Field-observed 2026-07-26: an msys2-hosted bake of punk91 produced a 49,501,792-byte
bin/punk91.exe that failed at startup with
application-specific initialization failed: Cannot find a usable init.tcl
because the host's tclsh had no tcllib and therefore could not extract the runtime's own zip. The previously working kit had already been replaced by then. G-124 removes the particular cause, but not the class: a runtime with no attached payload at all, an extraction that fails for any other reason, or a future container type reaches the same state, and the build's response is still "warn and deploy".
The existing precedent in the same code path is vfs_startup_script_warning, which warns
about a missing main.tcl and continues - deliberately, because a kit without a startup
script is legal. A kit without a resolvable tcl library is not in the same category: it
cannot initialise at all.
Approach
- Gate on the BOOT PRECONDITION, not on the extraction step having run. Some .vfs folders
legitimately supply their own tcl library (the merged
targetvfsis what matters), so the check inspects the assembled tree rather than the extraction outcome - a runtime that needed no extraction must keep building. - Fail the kit the same way every other failure in that loop does (append to
failed_kitswith a reason, end the punkcheck event FAILED) BEFORE the artifact is renamed into place, so neithersrc/_build/<kit>norbin/<kit>is touched and the punkcheck records stay consistent with what is on disk. - Keep it cheap and non-executing: a structural check of the merged vfs, no artifact launch, so it can run for every kit on every bake.
- The recapped BUILD-WARNING wording changes from "will not initialise unless the vfs supplies one" to a failure reason, since the gate now enforces what the warning described.
Alternatives considered
- Keep warning and deploying, on the grounds that the developer sees the recap - rejected: the recap arrives after the deployed kit has already been replaced, and the failure surfaces later as an unexplained broken shell. A build tool should not make a working executable worse.
- Boot the freshly built artifact as the check - rejected: it cannot work for cross-target kits (G-122 makes those routine), costs a process launch per kit, and a kit that boots into an interactive shell is awkward to probe safely.
- Emit to
src/_buildbut refuse only the deploy - rejected as a half-measure that leaves a punkcheck record claiming a good build product; a later run would consider it current.
Notes
- Related: G-124 - removes the most common cause (no zip reader on a tcllib-less tclsh). This gate is independent of it and remains valuable afterwards.
- Related: G-122 (achieved) - promoted the no-extraction notice to a recapped BUILD-WARNING and recorded the field incident that motivates this goal; see goals/archive/G-122-host-target-platform-split.md.
- Related: G-101 - a new 8.6 container type is exactly the situation where an extraction path can silently produce nothing; the gate is what keeps that honest.
- Related: G-028 - sibling failure-reporting surface in the same deploy step (that goal names the process holding a target the build cannot replace; this one refuses to replace a target with something unbootable).
- Overlap survey also considered G-057 (icon embedding rides the same wrap steps) and G-115 (declarative .vfs composition decides what the vfs supplies) - neither is a dependency: this gate reads whatever the merged tree contains, however it was composed.