From 43973fa5fdbb68482fdaff9530e5ce7ff7fca73f Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sun, 9 Aug 2026 14:04:16 +1000 Subject: [PATCH] goals: draft G-179 punk::args discriminator shadowing (opt-in -formselection literalshadow) Follow-through from G-174: with the walk conserving the tail, 'i a? web green' honestly reports the web/sample ambiguity - but a?'s implementation is literal-first else-branch dispatch, so the loose sample form can never receive a sibling form's literal discriminator word. The declaration over-admits, and per-type exclusion lists would be cross-referential drift. G-179 (proposed): definition-level opt-in (-formselection literalshadow) - among clean matches, a form whose leading discriminator run (literal/ literalprefix alternates or restricted choice sets, form_literal_affinity's notion) agreed with the supplied words shadows forms accepting the same word positions only via loose types. Loose-vs-loose ambiguity stays honest, noformmatch ranking untouched, undeclared definitions byte-identical, shadowed forms stay introspectable in formstatus; punk::ansi::a? adoption plus the three cmdhelp.test G-174 presentation-pin flips are in the acceptance. Related: G-041 (opt-in carve-out from its no-preference default), G-167 (sibling candidacy filter at the same seam), G-152/G-164, G-150, G-083, G-174, G-175, G-177, G-072. Collateral: the G-174 archived follow-on ("tighten a?'s loose sample form" => declined) re-dispositioned to => goal G-179 - this goal enacts its intent by declaration-level means rather than the type-exclusion approach the decline was about. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- GOALS.md | 4 + .../G-179-punkargs-discriminator-shadowing.md | 95 +++++++++++++++++++ .../G-174-cmdtraverse-word-accounting.md | 2 +- 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 goals/G-179-punkargs-discriminator-shadowing.md diff --git a/GOALS.md b/GOALS.md index 272dc5cb..7f3ad82b 100644 --- a/GOALS.md +++ b/GOALS.md @@ -408,3 +408,7 @@ Detail: goals/G-177-punkargs-scale-independence.md Scope: src/modules/punk/args-999999.0a1.0.tm (duplicate-id detection and policy, register protocol idempotency and diagnostics, definition format-level declaration, display-field command-substitution trust boundary); src/modules/AGENTS.md (third-party definition authoring guidance); src/tests/modules/punk/args/testsuites/args/ (new coverage) Detail: goals/G-178-punkargs-multi-provider-safety.md +### G-179 [proposed] punk::args discriminator shadowing - literal-backed forms shadow loose-typed clean matches (opt-in -formselection) +Scope: src/modules/punk/args-999999.0a1.0.tm (clean-match candidacy filter at the multipleformmatches seam, -formselection declaration + define-time validation, formstatus shadowed surface, form_literal_affinity reuse); src/modules/punk/ansi-999999.0a1.0.tm (punk::ansi::a? argdoc adopts literalshadow); src/modules/punk/ns-999999.0a1.0.tm (synopsis markforms + cmdhelp narrowing exclude shadowed forms); src/tests/modules/punk/args/testsuites/args/ (formselection candidacy/parse/parse_status pins); src/tests/modules/punk/ns/testsuites/ns/cmdhelp.test (deliberate G-174 presentation-pin flips) +Detail: goals/G-179-punkargs-discriminator-shadowing.md + diff --git a/goals/G-179-punkargs-discriminator-shadowing.md b/goals/G-179-punkargs-discriminator-shadowing.md new file mode 100644 index 00000000..f35322a8 --- /dev/null +++ b/goals/G-179-punkargs-discriminator-shadowing.md @@ -0,0 +1,95 @@ +# G-179 punk::args discriminator shadowing - literal-backed forms shadow loose-typed clean matches + +Status: proposed +Scope: src/modules/punk/args-999999.0a1.0.tm (clean-match candidacy filter at the multipleformmatches seam, -formselection declaration + define-time validation, formstatus shadowed surface, form_literal_affinity reuse); src/modules/punk/ansi-999999.0a1.0.tm (punk::ansi::a? argdoc adopts literalshadow); src/modules/punk/ns-999999.0a1.0.tm (synopsis markforms + cmdhelp narrowing exclude shadowed forms); src/tests/modules/punk/args/testsuites/args/ (formselection candidacy/parse/parse_status pins); src/tests/modules/punk/ns/testsuites/ns/cmdhelp.test (deliberate G-174 presentation-pin flips) +Goal: punk::args multiform definitions can declare once, at definition level (-formselection literalshadow on @cmd), that leading-discriminator agreement resolves clean-match ambiguity: a form whose leading discriminator run (literal/literalprefix alternates or restricted choice sets - form_literal_affinity's existing notion, leaders-then-values, shared choiceword_match resolution) agreed with the supplied words shadows forms that accepted the same word positions only via loose types - so else-branch dispatch commands like punk::ansi::a? are modelled without cross-referential type exclusions, punk::args::parse selects the discriminated form instead of raising multipleformmatches, help/synopsis narrowing follows, loose-vs-loose ambiguity stays honestly reported, shadowed forms remain introspectable in formstatus, and undeclared definitions keep today's G-041 behaviour byte-identically. +Acceptance: with a fixture declaring -formselection literalshadow: punk::args::parse of a line cleanly matching a literal-discriminated form and a loose form selects the discriminated form (no multipleformmatches raise) and parse_status reports ok=1 with that form while the shadowed form remains introspectable in formstatus (surface shape decided and recorded in this file - additive field per the G-167 style, or a distinct status value - with punk::ns synopsis markforms and cmdhelp narrowing excluding shadowed forms either way); a mixed-alternate argument matched via its loose alternate does not shadow; a restricted-choice discriminator shadows like a literal; two loose forms matching together still report multipleformmatches; noformmatch lines keep the existing ranked candidate display; the incomplete-line interaction (G-152/G-164 viability probe) has a decided, pinned behaviour recorded in this file; an unknown -formselection value is a define/resolve-time error; definitions without the declaration parse and render byte-identically (full punk/args suite green, none weakened); punk::ansi::a? adopts the declaration so 'i a? web green' renders web's usage alone and 's a? web green' marks web alone, with the three cmdhelp.test G-174 presentation pins deliberately flipped while cmdflow.test's G-174 conservation pins (args_remaining={web green}) hold unchanged; the punk/args and punk/ns suites pass under the canonical runtests interpreter. + +## Context + +Follow-through from G-174 (achieved 2026-08-09, goals/archive/G-174-cmdtraverse-word-accounting.md). +With the walk conserving the tail, 'i a? web green' now presents the web/sample +multipleformmatches ambiguity - technically honest against the DECLARATION, but false +of the FUNCTION: a?'s implementation is if/elseif/else dispatch (literal discriminators +first, treat-as-colourcodes as the else branch), so the sample form can never receive a +first word equal to a sibling form's literal. The declaration over-admits. Patching +sample's -type alternates to exclude sibling literals would be cross-referential and +drift-prone (user-rejected direction, 2026-08-09): each new panel form would silently +invalidate the loose form's type list. + +Two machinery facts make a declarative fix cheap: +1. form_literal_affinity (args tm ~7683) already classifies leading discriminator runs + (literal/literalprefix alternates AND restricted choice sets, leaders-then-values, + shared choiceword_match resolver) - today ranking/display-only by the G-041 + decision ("candidacy itself always comes from real parse attempts"). +2. punk::args::parse raises multipleformmatches on several clean matches (~10738, + "no silent preference"). The flag therefore has parse-level payoff, not just + presentation: it is what would let a?-class procs adopt punk::args::parse for real + dispatch. + +G-167 (proposed) already carves a deliberate, declared exception to no-silent-preference +at the same candidacy seam (available form beats unavailable form - "documentation never +competes with reality"). G-179 is the discriminator-based sibling: declared literal +agreement encodes dispatch reality. + +## Approach + +- Filter at the clean-match seam only: where candidacy today lands in the + multipleformmatches arms (parse raise ~10815, parse_status ~7297/~8473), apply the + shadow rule when the definition declares literalshadow; noformmatch ranking and all + single-match paths untouched. No additional by-id resolves (G-175 concern) and no + cost on the common paths (G-177 concern) - the filter runs only when several forms + matched cleanly. +- Reuse/extend the form_literal_affinity walk to report agreed word indexes and + whether agreement came via a discriminator alternate (matched-alternate precision: + literal(web)|string matched via string must not shadow). +- Declaration storage + define/resolve-time validation of the -formselection value + (spelling decision recorded: @cmd flag vs a bare directive like @dynamic). +- Consumers: punk::ns::synopsis markforms and cmdhelp's -form narrowing exclude + shadowed forms (shape depends on the formstatus surface decision). +- Adoption: a? argdoc declares literalshadow; flip the three cmdhelp.test G-174 + presentation pins (dict ok/failureclass/formstatus keys, text section set, synopsis + marking); cmdflow.test conservation pins unchanged. +- Same change-set as this draft: the G-174 archived Follow-on ("tighten a?'s loose + 'sample' form" => declined) re-dispositioned to => goal G-179 - this goal enacts its + intent by declaration-level means rather than the type-exclusion approach the + decline was about. + +## Alternatives considered + +- Per-form fallback tier (@form -matchtier fallback: form participates only when no + normal-tier form matches) - deferred, composable later; models non-literal + else-branches but encodes relative standing without cause and leaves literal-backed + vs loose overlap among normal forms unsolved. +- Ordered choice (first clean match in declaration order wins) - rejected: silently + prefers among ANY pair including genuinely ambiguous loose pairs; over-broad. +- Per-type exclusion lists on the loose form - rejected: cross-referential drift trap + (the motivating complaint). + +## Notes + +- Related: G-041 (archived - established no-silent-preference as the DEFAULT; this is + an opt-in declared carve-out, default byte-identical). G-167 (proposed - sibling + candidacy filter at the same seam with its own declared exception and the additive + formstatus-field style; whichever lands second inherits a merge obligation at the + filter seam). G-152/G-164 (archived - viability/incomplete-line semantics the filter + must compose with; decision item). G-150 (archived - flag-led narrowing pins on the + selection-sound hash declaration; same contract family). G-083 (archived - + declaration-level relational semantics precedent incl define-time validation and + render annotations). G-174 (archived - the consumer surface that exposed the + mismatch; its cmdhelp presentation pins flip deliberately here). G-175 (proposed - + render/resolve multiplicity: the filter must add no by-id fetches). G-177 (proposed - + scale: filter cost confined to the ambiguity path). G-072 (proposed - compound clause + types will extend the type-alternate vocabulary; the discriminator classification + must stay coherent with it). +- Decision items to record during the work: formstatus surface shape (additive + 'shadowed' field per G-167 style vs distinct status value - constraint: existing + status-eq-valid consumers must not mark shadowed forms); -formselection spelling + (@cmd flag vs bare directive); viability-probe interaction; optional usage-render + annotation on shadowable loose forms (G-083 'mutually exclusive'-note style, e.g + marking the else-branch form). +- Survey note: overlap survey run 2026-08-09 (goals_xref paths over the scope); + surfaced args-scoped goals not listed above (G-044, G-050, G-055, G-056, G-068, + G-069, G-075, G-088, G-178) reviewed and judged orthogonal (render/lint/registration + concerns, no candidacy-semantics contact); G-050 relates only through the already + recorded G-174 linkage. diff --git a/goals/archive/G-174-cmdtraverse-word-accounting.md b/goals/archive/G-174-cmdtraverse-word-accounting.md index 27ebff5d..76a7c1f8 100644 --- a/goals/archive/G-174-cmdtraverse-word-accounting.md +++ b/goals/archive/G-174-cmdtraverse-word-accounting.md @@ -201,5 +201,5 @@ Acceptance satisfied in full; flipped achieved 2026-08-09. ## Follow-ons Follow-on: cross-form traversal discrimination - extend cmd_traverse's first-form-only inspection (fid = first of form_names) so choices-bearing subcommand leaders on later forms are consulted during the walk; flip cmdflow.test cmdtraverse_firstformonly_recorded_limit when it lands => open -Follow-on: tighten punk::ansi::a?'s loose 'sample' form so discriminator words do not ambiguate => declined 2026-08-09 (the marked-ambiguity presentation is the G-041 multipleformmatches contract - drafting-time default confirmed at landing) +Follow-on: tighten punk::ansi::a?'s loose 'sample' form so discriminator words do not ambiguate => goal G-179 Follow-on: eparam double-listing corner - with nonempty eparams the code-3/code-11 remaining shape prepends already-consumed -ensembleparameter words beyond the sanctioned descent re-presentation (hand-authored -ensembleparameter-then-choiceless-leader first forms only; no shipped definition has the shape) => open