# G-042 Subshell-declared help topics via punk::config with defined shadowing policy Status: proposed Scope: src/modules/punk-999999.0a1.0.tm (::punk::helptopic registry), src/modules/punk/config-0.1.tm (stored declaration source), src/modules/punk/repl-999999.0a1.0.tm (subshell entry/exit hooks) Goal: a named subshell can declare its own help topics (name, aliases, summary, text content) in punk::config stored configuration - registered into the ::punk::helptopic registry on subshell entry and removed/restored on exit - so 'help' inside a customised subshell presents that subshell's topics with 'help topics' and 'i help' staying accurate (the registry already regenerates the punk::args definitions), under a defined precedence policy between topics and command-name fallthrough. Acceptance: a subshell whose configuration declares at least one custom topic shows it in 'help topics' and renders its configured content via 'help ' inside that subshell, and 'i help' lists it as a documented choice; on quit/switch-away the parent's topic set is restored (no leakage, proven by declaring a topic in a subshell and checking the parent after exit); configuration is read through punk::config (toml per G-014 - no ad-hoc parsing) and a shell with no topic configuration behaves unchanged; config-declared topics are text-content only - they cannot name code to execute (or a recorded design decision to the contrary with its sandboxing rationale in the detail file); the shadowing policy is implemented and documented: a declared topic colliding with a built-in topic is rejected (or explicitly overrides per a documented rule), a topic name shadowing a command name wins over command fallthrough as today with 'i '/'s ' documented as the command-help escape hatch; depends on G-014 for the stored-config substrate - the registry-side registration/restore mechanism may land earlier behind a programmatic API, with the config binding completing when G-014 lands. ## Context Arose from the 2026-07-08 punk::help restructure (punk module 0.2.0), which replaced the monolithic help_chunks switch with the ::punk::helptopic registry: each topic is a handler proc plus a punk::args definition, and registering a topic (re)generates the ::punk::help / ::punk::help_chunks definitions so 'help topics' and the 'i help' documented choice table can never drift from the registered set. That registry was explicitly built as the seam for this goal: adding a topic at runtime already updates every documentation surface for free. The user's intent (2026-07-08, during the restructure): the help system should be usable as a default for customised (punk::config-enabled) subshells with their own topics. Today the topic set is small and largely orthogonal to command names, so topic-vs-command shadowing is a non-issue; once subshells declare arbitrary topics, the precedence between a topic word and the command-info fallthrough (help ) becomes a policy that must be explicit rather than accidental. ## Approach (sketch - to be refined when activated) 1. Registry side (can land ahead of G-014, programmatic API): - a generic text-topic handler: config-declared topics carry name, aliases, summary and body text; the handler renders the body as chunks (frametype-aware wrapping optional). No code execution from configuration - a topic cannot name a proc to run. This is deliberate: G-003/G-009 restricted subshells must be able to carry custom help without the config becoming an interp-escape vector. If handler-proc topics are ever wanted, record the sandboxing rationale here first. - register/deregister with scoping: subshell entry registers its declared topics, quit/switch-away restores the prior registry state. Natural shape: save/restore of the registry dict rides the same lifecycle as the G-008 console state sets (activatable per-subshell state), but the registry is punk-side data - no terminal interaction - so it need not wait for G-008. - collision rule at registration time: reject (or per documented rule, override) a declared topic whose name or alias matches a built-in topic; the existing register proc already errors on a missing handler - extend it to police names. 2. Config binding (gated on G-014): - declaration lives in punk::config stored configuration under the named-subshell scoping G-014 defines (a subshell resolves its own topics; unconfigured shells inherit nothing extra). All reading via punk::config API backed by tomlish. - shape sketch (indicative only): [subshell..helptopic.] with keys aliases, summary, body. 3. Shadowing policy: registered topics win over command fallthrough (unchanged); the escape hatch for a shadowed command name is 'i ' / 's ' (the first-class command-help route) - document it where the topic set is presented ('help topics' footer or the ::punk::help -help text). 4. Display: alias folding for declared topics inherits G-040's -choicealiases (achieved 2026-07-08 - see goals/archive/G-040-punkargs-choicealiases.md). ## Relationship to the intended plugin facility (code review 2026-07-08) Reconnaissance of punk::mix::init, punk::cap, punk::pluginmgr and punk::overlay maps the plugin stack the codebase already intends, which this goal must slot into: 1. Discovery/loading + trust boundary: tcllib pluginmgr-style safe-interp plugin loading. punk::pluginmgr-0.5.1.tm is a vendored fork of tcllib pluginmgr with initial divergence ("JN - diverging from tcllib" in LoadPlugin: direct plugin.tcl sourcing from plugin paths); punk::mix::init's todos record the known gaps (tcllib 0.5 bugs around .tm modules vs packages - reports submitted upstream - and control of module/library path ordering inside the safe interps). 2. Capability registration/validation: punk::cap - in-process and cooperative (its own doctools position tcllib pluginmgr as "an alternative which uses safe interpreters"). Provider packages declare (capname capdict) pairs via a registration object; handlers validate at registration (pkg_register veto) and expose api_ objects. punk.templates is the only handled capability today. 3. Capability-specific handler APIs: punk::cap::handlers::templates, whose pathtype vocabulary (module / adhoc / currentproject* / shellproject* / absolute) is the existing answer to from-kit vs from-src-tree resolution. Implications adopted for this goal: - The ::punk::helptopic programmatic registry API is the convergence point. Stored-config topics (this goal - text only) and any future plugin-provided topics (code-bearing, arriving as provider packages through the punk::cap layer - e.g. a punk.subshell or punk.helptopics capability - where provider trust is the plugin facility's concern) land in the same registry, under the same collision policy, with the same punk::args regeneration. Nothing in this goal's mechanism needs reworking for plugins later. - The text-only stance is reinforced, and the boundary is now principled rather than just cautious: punk::config declarations are data; code-bearing topic handlers belong to the plugin path where a validation/trust story (cap handler veto, pluginmgr safe interps) exists. - Subshell definitions as plugins: punk::overlay::import_commandset is the existing commandset composition mechanism (rename-imports a commandset namespace's exported commands under a prefix; explicitly designed so one commandset can serve multiple CLIs simultaneously), and its own documentation already records the intent "Todo - .toml configuration files for defining CLI configurations". A future subshell-definition plugin/profile would compose: commandset imports + help topics + config defaults (+ G-009 restrictions/theme). This goal deliberately builds only the help-topic slice, with the registration/restore API shaped so a composite subshell-definition capability can drive it. ## Alternatives considered - Handler-proc topics declared in config - rejected as the default: stored configuration must not be a code-execution vector, especially for restricted subshells (G-003/G-009). Text-only content covers the motivating use (subshell-specific guidance); revisit with a sandboxing design if real demand appears. - Per-subshell complete replacement of the help command itself - rejected: loses the registry's guarantee that 'help topics'/'i help' match reality, and every subshell would reinvent the overview/fallthrough machinery. - Waiting for G-008/G-009 profiles to carry topics as part of themed profiles - not required: the registry save/restore is plain data and can precede the theming goals; profiles can later bundle topic declarations as one more profile aspect. ## Notes - Dependencies: G-014 (punk::config toml + named-subshell scoping - the config substrate; itself gated on tomlish argdoc work upstream). Beneficial, not required: G-040 (alias display folding), G-008/G-009 (profile bundling), G-002/G-010 (non-nested subshells - the restore-on-switch semantics should be specified to survive that rework). - Seam already in place (punk 0.2.0): ::punk::helptopic::register / resolve / define_docs; 'help topics' derives from the registry; per-topic punk::args ids follow the ::punk::helptopic:: convention consumed by 'i help ' subhelp choiceinfo. - Related session records: goals/archive/G-040-punkargs-choicealiases.md (choice display folding), the 2026-07-08 CHANGELOG entries for punk 0.2.0 (registry) and punk::ns 0.1.1 (doc-lookup trace cleanup).