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.
 
 
 
 
 
 

6.0 KiB

G-031 Componentized kit boot: thin project-owned main + shared layout-owned boot core

Status: proposed Scope: src/vfs/_config/ (punk_main.tcl, project_main.tcl restructure), src/vfs/_vfscommon.vfs (boot core delivery), src/project_layouts/ (thin-main skeleton, via established sync channels) Goal: the per-project vfs main script becomes a thin project-owned file - declare the application's subcommands and launch defaults at clearly commented customization points, then hand over to a shared layout-owned boot core (vfs mounts, package modes and paths, libunknown, src-mode modpod registration) and default dispatch pulled in from within the kit - so project developers add app-specific subcommands without wading through or forking ~1000 lines of boot boilerplate, and boot improvements reach derived projects as pull-updatable payload instead of dying in vintage forks (tomlish_main.tcl: ~20 custom lines carrying a stale 500-line 2025 copy of the rest). Acceptance: punkshell's own kits boot through a thin main plus shared boot core with behaviour parity - package modes including src mode, existing tclsh/shellspy/punk/shell/script dispatch semantics, and supported vfs types (zipfs/metakit/cookfs) all unchanged; a project-specific subcommand is added by editing only the thin main at a commented customization point (proven end-to-end in a derived project - tomlish replacing its forked main is the natural first); the boot core ships as layout-owned payload (via _vfscommon/layout channels) and the thin main as a project-owned skeleton, per the G-027 ownership classification; the boot core is versioned/identifiable so a kit can report which boot-core vintage it carries (ties to G-025 stamping).

Context

src/vfs/_config/punk_main.tcl is a 1190-line single apply block mixing two very different concerns:

  • Boot machinery (~1060 lines): vfs mount detection (zipfs/metakit/cookfs), starkit handling, package-mode token parsing (dev/os/src/internal), module and auto_path setup, libunknown, src-mode #modpod registration.
  • Application dispatch (~100 lines at the tail): subcommand extraction and the tclsh/shellspy/punk/shell/script cases.

Every kit's main.tcl is already a fauxlink to one such file per project (main.tcl#..+_config+<name>_main.tcl#@punk::boot,merge_over), and derived projects fork the whole file to customize the tail. Measured cost (2026-07-07):

  • tomlish_main.tcl: 547 lines, of which the genuinely tomlish-specific dispatch tail is ~20 lines - the rest is a 2025-vintage copy of the boot boilerplate, already 632 diff-lines adrift from current punk_main in the first 450 lines. Boot improvements since (src mode, modpod registration) never reached it.
  • project_main.tcl (layout template): 901 lines, same story at template vintage.

A project developer wanting one custom subcommand must wade through - and then permanently own - a thousand lines of boot code.

Approach

  • Split into:
    • Boot core (layout-owned): the boot machinery plus the default dispatch, shipped inside the kit via _vfscommon.vfs (every kit already merges it) and sourced from the thin main by vfs-relative path. Layout-owned per the G-027 ownership classification -> pull-updatable in derived projects, so boot fixes propagate instead of dying in forks.
    • Thin project main (project-owned skeleton): declares project subcommands and launch defaults at clearly commented customization points, then hands over to the boot core. This is the file a project developer reads and edits.
  • Boot-phase constraint: the boot core cannot be a package (no package paths exist yet) - it is sourced by vfs-relative path from the thin main. The default dispatch portion runs post-boot and may be package-based if that proves cleaner; record the split point here when decided.
  • Registration model: the thin main declares subcommands (name -> handler package/command, plus optional punk::args definition id for G-032) before invoking the default dispatch; built-ins (tclsh/shellspy/punk/shell/script, and G-025's version-report) come from the boot core, project additions merge in. Default-subcommand and no-args behaviour are declared, not hardcoded (a shell-like default remains the punkshell behaviour; a tool-like default such as tomlish's -help injection becomes a declared choice).
  • Boot core carries its own version/identity so a kit can report the boot vintage it embeds (G-025 stamping is the natural vehicle).
  • Layout skeletons follow through the established sync channels (custom/ _project sync step now; G-012/G-027 for the rest) - noted in completion reports, never hand-synced.

Alternatives considered

  • Leaving the monolith and documenting "edit the tail" - rejected: the fork cost is proven (tomlish, project_main both adrift); documentation does not stop vintage divergence, pull-updatable payload does.
  • Making the entire main (incl. dispatch tail) layout-owned and pushing project customization into data/config only - rejected for now: subcommand handlers are code; a thin project-owned code file with a clear contract is simpler than inventing a config schema for arbitrary launch behaviour. Revisit if the thin mains themselves start accreting boilerplate.

Notes

  • Sequencing with G-015: resolved - G-015 proceeded first on the monolith (achieved 2026-07-07 as the dedicated app-punkscript package, see goals/archive/G-015-script-subcommand-piped-stdin.md), so its dispatch logic moves into the boot core here and this goal must preserve the script subcommand's behaviour.
  • Related: G-027 (ownership + pull channel this is designed for), G-025 (boot-core vintage reporting), G-032 (punk::args-defined dispatch built on the registration model), G-012 (layout payload hygiene), G-018 (plain tclsh kits deliberately carry NO punk boot layer - out of scope here).
  • The tomlish silent-exe incident (2026-07-07, tomlish 1.1.10 fix) is a reminder that launch-path contracts are easy to break invisibly - behaviour parity in the acceptance means exercising each dispatch case, not just booting.