6.6 KiB
G-075 punk::args (package) ids: working lookup and a user-facing package documentation surface
Status: proposed Scope: src/modules/punk/args-999999.0a1.0.tm (id lookup/update_definitions prefix handling, usage/arg_error rendering of package-level ids), src/modules/punk/ns-999999.0a1.0.tm (cmdhelp/help-system surface), src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/modules/template_module-0.0.4.tm (template block as touched/verified), src/tests/modules/punk/args/testsuites/args/ + src/tests/modules/punk/ns/testsuites/ns/ (new coverage) Goal: the "(package)" ids that the module template (dev module.new) and the punk::args::moduledoc::* packages already declare become functional and user-visible - the id lookup path handles the (package) prefix (today punk::args::id_exists returns 0 for them and update_definitions emits an unqualified-ns warning, because only the (autodef) prefix is stripped when deriving a namespace from an id), a package-level id renders its @package -name/-help as a package documentation page through the usage machinery, and the interactive help surface reaches it ('i ' presenting the package doc when resolves to a documented package rather than a command - exact surface decided in the work), making @package -help the natural home for per-package conventions and usage notes (e.g a moduledoc's harvest/provenance conventions). Acceptance: punk::args::id_exists returns true for a registered "(package)" id after its namespace's scan (the update_definitions "received unqualified ns" warning no longer fires for (package)-prefixed lookups); punk::args::usage renders a (package) id via the @package directive's fields (render shape decided in the work - it has no arguments table unless the definition adds directives; at minimum -name and -help present cleanly in table and string renderers); the interactive surface is decided, documented and implemented ('i ' or documented equivalent) with behaviour defined for the name-collision case (a namespace that is both a documented package and an ensemble command); the four moduledoc (package) ids (iocp, parser, tkcore, tzint) and at least one template-created module's id render through the new surface; the template's (package) block is verified as-written (or minimally corrected in step, with the template version bumped per its conventions); discoverability exists in some listed form (e.g ids matching (package)* via an existing query/listing command - decided in the work); new tests cover lookup, rendering and the interactive surface; full punk::args and punk::ns suites pass.
Context
User context 2026-07-13: the (package) ids were intended somewhat as the surface for package-level documentation/guidance but "aren't yet surfaced to the user"; they come from the module template, so most modules created with 'dev module.new' carry one.
Probed state (2026-07-13, tclsh 9.0.3): 45 modules under src/modules declare @id -id "(package)" blocks with an @package -name/-help directive (template_module-0.0.4.tm carries the canonical block). They are currently inert:
- punk::args::id_exists "(package)punk::args::moduledoc::parser" returns 0 even with the package loaded and registered.
- The lookup emits: warning: update_definitions received unqualified ns: (package)punk::args::moduledoc - real_id derives a namespace from the id's qualifiers, and only the (autodef) prefix is special-cased/stripped; the (package) prefix flows into the namespace name.
- The resolver itself understands the @package directive (the spec dict carries a package_info key alongside cmd_info/doc_info) - the gap is lookup and surfacing, not definition storage.
The immediate motivation is the guidance-space discussion (recorded in G-055 and the punk::args 0.11.1 define doc): system-wide authoring mechanics now live in the punk::args::define help, and per-package conventions (harvests, provenance, version adaptivity of a moduledoc) belong with the package - @package -help is the declared place, once reachable.
Approach
- Lookup: extend the prefix handling where namespaces are derived from ids (real_id/update_definitions) so "(package)" is recognised like "(autodef)" - the namespace for scan purposes is the id minus the prefix. Verify tail-colon handling ((package) ids name namespaces, not commands - the id has no command tail).
- Rendering: punk::args::usage on a (package) id - drive the existing arg_error machinery with package_info (title/name/help; no Arg table rows unless the definition declares arguments). Check interaction with the synopsis section (suppress or render a package-appropriate header).
- Interactive surface: punk::ns::cmdhelp fallback - when the query word is not a command but matches a documented package/namespace, present the package page. Collision rule (documented): a real command (e.g an ensemble named for the namespace) wins; the package doc is reachable explicitly (spelling decided - e.g 'i (package)foo::bar' at minimum).
- Discoverability: a listing of documented packages (existing id query/listing machinery filtered on the prefix, or a punk::args::status extension).
- Template: verify the template block round-trips through the fixed path; the moduledoc (package) blocks likewise (tclcore notably has none - adding one is a natural but optional step recorded either way).
Notes
- Related: G-055 (per-package conventions/provenance belong in @package -help once surfaced; its workflow doc should point there when this lands), G-042 (subshell help topics - adjacent help-surface work; keep the surfaces consistent), G-017/G-068 (package-level documentation consumers).
- The punk::args::define help (0.11.1) documents registration styles and defspace rules system-wide; this goal's surface is where the per-package layer of that guidance becomes reachable.
- 45 declaring modules found 2026-07-13 via grep for '"(package)' under src/modules (plus decktemplates vendor copies); count will drift - the acceptance names the four moduledocs + one template-created module as the proving set, not all 45.
- Adjacent id-rendering nicety parked here 2026-07-14 (G-030 lesson): the auto-generated synopsis renders the definition id, not @cmd -name - so script-level/constructed ids like (script)::punkboot::modules display raw unless an explicit @form -synopsis is supplied (make.tcl does this; the authoring-ergonomics bullet in src/modules/AGENTS.md documents it). While reworking how non-command id prefixes render, consider a synopsis fallback to @cmd -name when the id is not a real command path. (G-030 achieved 2026-07-14 - goals/archive/G-030-maketcl-punkargs.md)