You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4.4 KiB

G-019 Dependency-scan-driven module trimming for punk-based executables

Status: proposed Scope: src/make.tcl, src/modules/punk/lib-999999.0a1.0.tm (tclparser use), src/vfs/ (kit assembly), scanning module (new or existing punk module - to be determined) Goal: a package-dependency scan from an executable's entrypoint (candidate basis: the tclparser parse API - currently satisfied only by the c-only tclparser library, with punk::lib's pure-Tcl fallback an unimplemented stub) determines the module closure the executable actually requires, so a build can ship only those modules - while 'batteries included' builds remain a supported alternative, not a casualty. Acceptance: for at least one punk-based executable target, the build can run a dependency scan from its entrypoint producing the closure of required packages/modules plus a mechanism to declare dynamically-loaded extras the scan cannot see; a trimmed kit assembled from that closure starts and passes its basic function check (e.g. repl launch or the app's smoke test) with no missing-package errors; the trimmed kit's module listing is a strict subset of the batteries-included equivalent (demonstrating real exclusion); batteries-included builds remain producible unchanged.

Context

Punk executables are currently 'batteries included' - the kit assembly ships the full module snapshot regardless of what a given executable's app actually uses. For executables built around a specific app or entrypoint, a package-dependency scan could determine the module closure genuinely required and let the build ship only that, giving smaller artifacts. Batteries-included builds remain a supported alternative (the middle and far points of the spectrum described in G-018's context section).

The candidate scanning basis is static parsing of Tcl source via the tclparser parse API (tclpro-descended; https://wiki.tcl-lang.org/page/tclparser). Its current availability shapes the work:

  • The real implementation is the c-only tclparser library (package require parser); punk::lib uses it opportunistically.
  • punk::lib carries a same-API pure-Tcl fallback, punk::lib::tclparser_tcl (src/modules/punk/lib-999999.0a1.0.tm ~3322), which is an unimplemented stub that errors advising installation of the C library.
  • punk::args::moduledoc::parser documents the parse API.

Using the C library inside build tooling makes the build depend on a native binary - intersecting the G-004/G-005/G-006 binary-provenance story (zig-built or consent-downloaded, never committed). Completing the pure-Tcl fallback would remove that coupling at some accuracy/performance cost. The choice (or ordering

  • e.g. C library first, fallback later) is an implementation decision to record here.

Approach

  • Static scan from the executable's entrypoint/app: walk package require (and tcl::tm / source-time load constructs) through the reachable sources, resolving the transitive closure against the project's module trees.
  • Dynamic requires are the known limit: computed package names, plugin-style loading, and package require inside rarely-hit code paths cannot be proven statically. A declaration mechanism for extras (per-executable manifest of packages to include beyond the scan result) is part of the goal's acceptance, not an afterthought.
  • Scan output should be a reviewable artifact (the closure list), feeding kit assembly rather than silently filtering it - so a wrong exclusion is diagnosable from the build record.
  • Verification of a trimmed kit is behavioural (starts, passes its app's smoke check) plus structural (module listing strictly a subset of the batteries-included equivalent).

Alternatives considered

  • Runtime tracing (run the app, record package require calls) instead of static parsing - rejected as primary: coverage-dependent (only exercised paths are seen), though it could later complement the static scan for validating the declared-extras list.
  • Naive regex scan for package require lines - rejected: misses computed names it can't even flag, false-positives in strings/comments; the tclparser parse API exists precisely to do this properly.

Notes

  • Interacts with G-005/G-006 (how the c-only tclparser binary is provisioned if chosen) and G-018 (the spectrum of executable flavours).
  • punk::lib sites already noting tclparser use/fallback: tclword_to_scriptlist and related parsing helpers (~lib 3322-3580).