7.2 KiB
G-166 cmdinfo/cmdhelp surface recognised-but-unavailable landings distinctly
Status: proposed Scope: src/modules/punk/ns-999999.0a1.0.tm (cmdinfo result key, cmd_traverse landing attribution, cmdhelp render marking + advisory-parse presentation); src/modules/punk/args/moduledoc/tclcore-999999.0a1.0.tm (virtual ids lead with the unavailability note on affected runtimes); src/tests/modules/punk/ns/testsuites/ns/ (cmdinfo/cmdhelp pins incl the deliberate key-list flip); src/tests/modules/punk/args/testsuites/args/tclcoreparity.test (8.6-arm pins) Goal: cmdinfo/cmdhelp surface recognised-but-unavailable landings: cmdinfo gains an availability key (empty, or the canonical unavailable word) populated wherever resolution addresses a -choiceunavailable word (exact space-form docid landings and the choice traverse), cmdhelp marks such subjects visibly in all return forms and its advisory parse no longer presents them as cleanly usable, the tclcore virtual ids lead with the unavailability note on affected runtimes, and the doc walk's treatment of a unique prefix landing on an unavailable name (currently: resolves no documentation) is decided and pinned within this goal - with the enacted G-073 follow-on items dispositioned accordingly. Acceptance: on a runtime where the tclcore model declares dict unavailable (Tcl 8.6), cmdinfo for 'string is dict' (direct and decomposed invocation forms) reports the new availability key carrying 'dict' while 'string is true' reports it empty, with cmdtype remaining 'doconly' for both (the command-kind axis is not overloaded); the key is present on every cmdinfo result and the cmdhelp.test cmdinfo key-list pin is flipped deliberately; cmdhelp output for an unavailable subject is visibly distinguished in table, text and dict return forms (the dict form carries the key; table/text carry a marking naming the unavailability), and an argument tail such as 'string is dict 5' no longer renders as a cleanly usable command line; the walk's unique-prefix landing on an unavailable name ('i string is dic' on 8.6) has a decided, pinned behaviour consistent with the marking (either resolving the virtual docid WITH the marking, or documented-conservative non-resolution); tclcore virtual ids for unavailable classes lead their rendered help with the unavailability statement on affected runtimes (first description line, not buried mid-prose) while modern runtimes render those ids unchanged; definitions without -choiceunavailable and existing cmdinfo/cmdhelp consumers behave unchanged (full punk/ns and punk/args suites green apart from deliberately flipped pins); the enacted G-073 Follow-on lines carry => goal G-166 dispositions.
Context
Found 2026-08-05 immediately after G-073 achieved (user probes): on Tcl 8.6, 'i ::tcl::string::is dict' (unavailable class) and 'i ::tcl::string::is true' (real class) produce indistinguishable machine shapes - cmdinfo reports cmdtype 'doconly' with identical key sets for both, and cmdhelp's advisory parse of an argument tail ('string is dict 5') succeeds against the virtual id so the render presents the unavailable class exactly like a usable one. The only difference is the "(class not present in Tcl 8.6)" sentence mid-way through the description prose.
Half of this is G-073's intent: documentation REACHABILITY for unavailable words (via exact space-form virtual docids) is an acceptance requirement, and doc addressing has always been deliberately broader than parse acceptance (per-class ids like 'string is true' document argument words that were never subcommands). The INDISTINGUISHABILITY is emergent, not specified: nothing structural tells a consumer - human or machine - that the documented word is rejected by this runtime's parse.
Axis decision (assessed 2026-08-05, to be confirmed in the work): a NEW cmdinfo key, not a cmdtype refinement such as 'doconly_unavailable'. cmdtype answers "what kind of executable thing did resolution land on"; availability is a property of the resolved word at its level. Today they co-occur with doconly only incidentally (unavailable entries never have real commands behind them), and overloading the value breaks consumers switching on cmdtype eq "doconly". The two-axes distinction is recorded in the cmd_traverse choice-traverse comment (ns 0.9.3).
Approach
- New cmdinfo result key (spelling decided in the work; candidate 'unavailable' - empty string normally, the canonical unavailable word when the resolution addressed one). Population is nearly free: the choice traverse already holds the resolver's matchinfo (its 'unavailable' key, punk::args 0.16.0), and the exact space-form id landing branches can consult the level's choices-bearing arginfo the same way the space-form prefix-parity branch (G-051, achieved 2026-07-13 - see goals/archive/G-051-cmdinfo-pseudo-and-prefix.md) already does (Dict_getdef -choiceunavailable + membership check).
- cmdhelp derives the render marking from the same data: a visible unavailability statement in table/text forms (warn styling; placement decided in the work - title line marker and/or a leading line), the key in -return dict, and the advisory-parse presentation adjusted so an accepted parse against an unavailable subject's virtual id is not shown as a cleanly usable command line.
- tclcore generator: on runtimes where a forward class is unavailable, the per-class virtual id's help LEADS with the unavailability statement (the static description follows); modern runtimes generate the id unchanged.
- Prefix-landing decision: either the walk resolves a unique prefix landing to the virtual docid and relies on the marking to carry the rejection story (parse gives the tailored "resolves to 'dict'" report for the same word), or the current conservative non-resolution is kept and pinned as deliberate. Decided in the work; the G-073 follow-on line flips accordingly.
Notes
- Related: G-073 (achieved 2026-08-05, archived - goals/archive/G-073-punkargs-unavailable-choices.md) - this goal enacts its open follow-on on doc-walk prefix landings and resolves the indistinguishability its acceptance did not specify; the -choiceunavailable key, resolver indication and tailored parse rejection this goal consumes all landed there (punk::args 0.16.0, tclcore moduledoc 0.4.0, ns 0.9.3).
- Related: G-050 (punk::ns::synopsis argument-validity marking and status-aware returns) - sibling display-marking surface; whichever lands second should reuse the first's marking vocabulary/styling decisions.
- Related: G-044 (completion/hinting) - a future consumer: completion over choices should be able to exclude or annotate unavailable words from the same data rather than re-deriving.
- Related: G-055 (tclcore moduledoc regeneration workflow) - the tclcore virtual-id leading-note change lands in the moduledoc G-055's workflow governs; its guidance gains the forward-class pattern per the G-073 follow-on already dispositioned => goal G-055.
- Overlap survey 2026-08-05: goals_xref paths src/modules/punk/ns-999999.0a1.0.tm
- G-044/G-050/G-052/G-075/G-085 surfaced; G-052 (TclOO autodef) and G-085 (cmdtrace) are same-file unrelated concerns; G-075 ((package) ids) is sibling docid territory with no word-availability interaction - deliberate non-overlap.