Browse Source

add goals G-031/G-032: componentized kit boot + punk::args launcher

G-031: split the monolithic vfs main (punk_main.tcl: 1190-line apply
block - ~1060 lines boot machinery, ~100 lines dispatch tail) into a
layout-owned boot core (shipped via _vfscommon.vfs, sourced by
vfs-relative path since no package paths exist at boot; pull-updatable
per the G-027 ownership model) and a thin project-owned main declaring
app subcommands at commented customization points. Fork cost measured:
tomlish_main.tcl carries ~20 custom lines on a stale 500-line 2025
vintage copy; project_main.tcl (901 lines) same at template vintage -
boot improvements never reach derived projects. Acceptance: behaviour
parity across dispatch cases and vfs types, project subcommand added by
editing only the thin main (tomlish the proving ground), boot core
versioned/reportable (G-025).

G-032: the default dispatch defines subcommands via punk::args - tabled
-help enumerating built-in and project-registered subcommands, parsed
options with tabled usage errors (script/G-015 or version-report/G-025
as first candidates), G-030 degradation rules (guarded require; parsing
falls back to switch semantics, help to a plain list; rendering degrades
independently). Parked decision: the silent unknown-arg->script
reclassification should stop swallowing typos (candidate rule:
reclassify only when the argument names an existing file).

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 1 week ago
parent
commit
c662ed1ed5
  1. 12
      GOALS.md
  2. 84
      goals/G-031-componentized-kit-boot.md
  3. 58
      goals/G-032-launcher-punkargs.md

12
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 <subcommand>` (or `<subcommand> -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 - `<punkexe> -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: `<punkexe> -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.

84
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+<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
`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.

58
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. `<punkexe> -help`, `<punkexe> help <subcommand>`, and
`<subcommand> -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).
Loading…
Cancel
Save