# 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) Acceptance: as in root GOALS.md index (canonical). ## 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+_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 `source`d 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: the script-subcommand work touches the same dispatch tail. Either order works, but whichever lands second must preserve the other's behaviour; if G-015 proceeds first on the monolith, its dispatch logic moves into the boot core here. - 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.