diff --git a/GOALS.md b/GOALS.md index a836d9b0..31770c1b 100644 --- a/GOALS.md +++ b/GOALS.md @@ -228,3 +228,15 @@ Scope: src/make.tcl (dispatch, help, prompts), src/bootsupport/AGENTS.md + src/m Detail: goals/G-030-maketcl-punkargs.md Goal: make.tcl - the first surface a developer sees - parses its subcommands and options via punk::args and showcases the tabled usage output for help and argument errors, every interactive y/n prompt gains a declared flag equivalent so agents can drive make.tcl with arguments instead of piped input, punk::args joins the bootstrap-tracked staleness set, and the boot phase plus the environment-repair commands keep working with degraded plain help when the bootsupport punk::args (or the table-rendering stack) is stale or unavailable. Acceptance: `tclsh src/make.tcl` and `-help` render punk::args tabled usage listing every subcommand with a summary, and `make.tcl help ` (or ` -help`) shows that subcommand's definition; invalid arguments produce a punk::args usage error rather than ad-hoc messages; every y/n prompt has a documented flag equivalent (proven at least for vfscommonupdate and the project-build confirmations: a run with the flag completes non-interactively with stdin closed) and a non-interactive stdin without the flag fails fast with usage rather than hanging or half-aborting; punk::args is added to the bootstrap-tracked buildversion set with the doc contract updated (src/bootsupport/AGENTS.md, src/modules/AGENTS.md); with bootsupport punk::args unavailable or unloadable, make.tcl still boots and `check`, `bootsupport` and `modules` remain usable with plain-text fallback help (the guarded-require degrade rule); layout make.tcl copies follow via the established sync/G-027 channels (noted, not hand-synced). + +### G-031 [proposed] Componentized kit boot: thin project-owned main + shared layout-owned boot core +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) +Detail: goals/G-031-componentized-kit-boot.md +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). + +### G-032 [proposed] Kit launcher dogfoods punk::args: tabled help and parsed subcommands +Scope: src/vfs/_config/ (default dispatch), src/lib/app-punkshell and sibling app packages as touched +Detail: goals/G-032-launcher-punkargs.md +Goal: the default launch dispatch defines its subcommands via punk::args - ` -help` and argument errors render the tabled usage enumerating built-in and project-registered subcommands with summaries, and subcommand options parse through punk::args so projects can declare complex arguments - with the G-030 degradation rules (boot never fails and help degrades to plain text when punk::args or the ANSI rendering stack is unavailable). +Acceptance: ` -help` renders tabled usage listing all subcommands including project-registered ones, each with a summary; at least one built-in subcommand's options are declared and parsed via punk::args with tabled usage errors on invalid input (the G-015 script subcommand or the G-025 version-report subcommand are the natural candidates); a project-registered subcommand's help appears by registration alone - no edits to the shared dispatch; with punk::args or the rendering stack unloadable, boot proceeds and help degrades to a plain subcommand list; verified on both a zipfs-based and a non-zipfs kit where both remain supported. diff --git a/goals/G-031-componentized-kit-boot.md b/goals/G-031-componentized-kit-boot.md new file mode 100644 index 00000000..042f345d --- /dev/null +++ b/goals/G-031-componentized-kit-boot.md @@ -0,0 +1,84 @@ +# 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. diff --git a/goals/G-032-launcher-punkargs.md b/goals/G-032-launcher-punkargs.md new file mode 100644 index 00000000..d44f60fb --- /dev/null +++ b/goals/G-032-launcher-punkargs.md @@ -0,0 +1,58 @@ +# G-032 Kit launcher dogfoods punk::args: tabled help and parsed subcommands + +Status: proposed +Scope: src/vfs/_config/ (default dispatch), src/lib/app-punkshell and sibling app packages as touched +Acceptance: as in root GOALS.md index (canonical). + +## Context + +The kit launcher is, alongside make.tcl (G-030), the first surface a user or +agent meets - and it should showcase the ecosystem's own argument tooling the +way the tomlish cmdline app already does (tabled usage on -help/no-args). +Today the dispatch in punk_main.tcl is a bare `switch` on the first argument +with no help output at all: an unknown first argument silently becomes a +`script` attempt, and there is no way to discover the subcommands +(tclsh/shellspy/punk/shell/script) or the package-mode tokens without reading +the source. + +Builds on G-031's registration model: the thin project main declares +subcommands with optional punk::args definition ids; the shared dispatch +renders and parses from those declarations - so a project's subcommands appear +in `-help` by registration alone. + +## Approach + +- punk::args definitions for the top-level dispatch (subcommand enumeration + with @cmd summaries, package-mode leader documented) and per-subcommand + options. ` -help`, ` help `, and + ` -help` all render tabled usage. +- Parse errors on declared subcommands produce punk::args usage errors + (tabled), not silent fallthrough. The unknown-first-arg -> script + reclassification survives only where it does not swallow obvious mistakes - + the exact rule is an implementation decision to record here (candidates: + reclassify only when the argument names an existing file, else usage error). +- **Degradation per the G-030 rules**: the kit normally bundles punk::args and + the rendering stack, but src/dev modes and damaged kits must not brick the + launcher - guarded lazy require; parsing degrades to the current switch + semantics and help to a plain subcommand list when punk::args (or the ANSI + stack, independently) is unavailable. +- Exit-code and output-cleanliness expectations follow G-015: help to stdout + exit 0; usage errors to stderr nonzero; no launcher chatter on the app's + channels. + +## Alternatives considered + +- Help text maintained by hand in the dispatch - rejected: the same + hand-maintained-help drift make.tcl has (G-030), and project-registered + subcommands would need dispatch edits to become discoverable. +- Requiring punk::args at boot - rejected: same repair-path reasoning as G-030 + and the punkboot::utils guarded-require rule. + +## Notes + +- Related: G-031 (registration model this renders from - soft prerequisite; + could proceed on the monolith but shouldn't), G-030 (make.tcl counterpart + and the shared degradation doctrine), G-015 (script subcommand options are a + natural first parsed subcommand; exit-code semantics), G-025 (version-report + subcommand born punk::args-defined), G-013 (the debugrepl activation review + mentions proper-command conversions that would slot into the same pattern).