You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

6.5 KiB

G-168 Selection-sound launch definitions: script/tclsh forms match dispatch reality

Status: proposed Scope: src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm ((script)::punkexe::script + ::tclsh form discrimination); src/lib/app-punkscript/punkscript.tcl (behaviour oracle, error-surface decision); src/vfs/_config/punkboot_core.tcl (only if the dispatch-parse decision adopts gating, + synced copies via established channels); src/tests/modules/punk/args/testsuites/args/ (new model-parity suite); src/tests/shell/testsuites/punkexe/launcherhelp.test (as touched) Goal: The two multi-form launch-subcommand definitions are parse-discriminable with existing punk::args vocabulary - form auto-selection agrees with actual dispatch/app behaviour: the file form excludes exactly '-e' (-regexprefail {^-e$}, message naming ./-e), the oneliner form declares the '-e' word as a real element, and tclsh's scriptfile-vs-stdin split (leading-dash words stay argv; incomplete -encoding falls through, stock-style) is expressed through candidacy fall-through - so parse_status verdicts, noformmatch diagnoses and downstream consumers (help depth, completion) see the truth instead of a display-only model. Acceptance: against the script definition, parse/parse_status select oneliner for {-e ...}, select file for { ...} where ne -e, and {-e} alone reports noformmatch with oneliner viable-incomplete (the app's "-e requires a script argument" reality); against tclsh, {file args} selects scriptfile, a leading-dash word selects stdin, and an incomplete -encoding tail falls through to stdin (stock parity); formcheck reports no unsanctioned findings; a real-vs-model probe matrix (G-055 method) against actual dispatch/app-punkscript behaviour is recorded in this file; whether DISPATCH adopts parse-gating for script/tclsh (tabled pointed errors replacing app-punkscript's plain ones) is decided and recorded with rationale and, if adopted, a measured script-launch latency delta; the new behaviour is pinned in the args testsuite and launcherhelp.test passes unchanged (or with deliberately updated pins named here).

Context

2026-08-05 discussion (formhint arc): 'punk9-dev -e' / 'script -e' error - word-1 '-e' is RESERVED by behaviour (app-punkscript punkscript.tcl:78-88; a file so named needs ./-e), but the file form declares scriptfile as any string - the definition is display-honest, parse-dishonest, and the forms cleanly double-match. The blocker assumed earlier (G-072 negation) is not needed: -regexprefail is honoured during form matching (verified in the G-143 make.tcl arc, achieved - goals/archive/G-143-maketcl-multiform-help.md; the G-150 selection-sound hash declaration is the dash-led-form-word precedent).

Notes

  • Enacts the punkexe portion of the G-150 follow-on "sweep other flat multi-form definitions for selection-soundness" (goals/archive/G-150-cmdhelp-form-narrowing.md); that follow-on stays open - the sweep is broader than these two definitions.
  • The G-144 follow-on (punkexe moduledoc @form -synopsis override set drops once auto-synopsis serves - goals/archive/G-144-punkargs-synopsis-name-fallback.md, disposition flipped to this goal) is decided in this work: keep the placeholder overrides or adopt @cmd -name auto lines - recorded either way.
  • Related: G-089 (proposed) - script's lib:name resolution text is consumed scope.
  • Related: G-055 (proposed) - the real-vs-model probe method borrowed here.
  • Related: G-072 (proposed) - deliberate non-dependency: negation NOT required.
  • Related: G-170 (proposed) - consumer: its dry-run arm requires this goal's parse-trueness.
  • Overlap survey 2026-08-05: goals_xref paths over the Scope - G-089 (named above) is the only substantive live intersection on punkboot_core.tcl; moduledoc-sibling matches (G-055 G-068 G-072 G-083 G-084 G-166 G-167) are parser/spec mechanisms or other moduledocs, no availability interaction.
  • 2026-08-05 pre-test findings (engine primitives probed on tclsh 9.0.3 and pinned green on tclsh90+tcl87: forms.test fencing/fall-through group, formviability_dangling_optional_option_conservative, errsel_dangling_option_trailing_value_overflow, formcheck_GAP_punkexe_*):
    • A -regexprefail rejection on an OPTIONAL value slot is fatal to that form's candidacy - the word does NOT re-land on a later permissive slot (contrast optional-CHOICE rejection, errsel_rejected_word_lands_later) - so per-slot fencing fences whole forms (forms_fence_optional_slot_no_reland).
    • Unknown options, dangling option words and option-satisfied-but-values-unmet tails each fail only their form: auto-selection falls through to a sibling as a SUCCESSFUL parse, and an option VALUE's -regexprefail participates in candidacy too - the stock "-encoding recognised only before a non-dash word" primitive is expressible (forms_fallthrough_* pins).
    • LIMIT for the tclsh model: a complete '-encoding ' line wordwise-matches both a fenced scriptfile form and any dash-tolerant stdin form; per-word constraints cannot express stock's "scriptfile wins when complete" priority, so the no-silent-preference contract (G-041, achieved - goals/archive/G-041-punkargs-form-matching.md) raises multipleformmatches (forms_fenced_pair_residual_overlap). The tclsh declaration must design around this class - form restructuring, an -overlapallowed sanction (display-only; parse still raises), or the dispatch-parse decision this goal already tables.
    • The {-e}-alone viable-incomplete acceptance rides the re-probe of G-164 (achieved 2026-08-04 - goals/archive/G-164-viability-alternative-allocation.md), which re-seats only words naming missing REQUIRED options: declare '-e' as a required -type none flag plus a separate required script value (the auto_exec::hash -r/-d shape), NOT as a value-taking option - a stolen word naming a value-taking or OPTIONAL option keeps verdict invalid (formviability_reprobe_value_taking_option_conservative and the new formviability_dangling_optional_option_conservative twin).
    • Before-state pinned as GAP: both punkexe multi-form definitions carry unsanctioned structural formcheck findings and every primary launch line double-matches ({-e X} / {file args} / {file} / {-encoding enc file}); empty input selects file/stdin uniquely (formcheck_GAP_punkexe_script_forms_overlap, formcheck_GAP_punkexe_tclsh_forms_overlap, formcheck_GAP_punkexe_primary_inputs_double_match - flipped deliberately by this goal per its Acceptance).