Browse Source
User-directed activation and implementation in one arc (proposed -> active at the user's word with the activation-freshness survey recorded, -> achieved + archived on acceptance). Co-location kills the doc-drift class: the actual '-e' parsing and its punk::args documentation now live in the same file. app-punkscript 1.2 + new package app-punkscript-docs 1.2 (same file): src/lib/app-punkscript/punkscript.tcl carries the (script)::punkexe::script definition (the G-168 selection-sound shape moved VERBATIM - value strings byte-identical, renders match the pre-handover moduledoc) in ::app::punkscript::argdoc with an idempotent docs section - a plain namespace-variable set plus a membership-guarded lappend to ::punk::args::register::NAMESPACES; no package requires, no punk::args dependency, no definition evaluation (lazy on the first query naming the id - the docpackages mechanism pinned ahead in docpackages.test). pkgIndex.tcl provides app-punkscript-docs from the SAME file via an execution gate (::app::punkscript::docs_only set around the source; the file returns after the docs section when the gate is up, and 'package provide app-punkscript' sits below the gate) - requiring the docs NEVER runs a script, and a later app require re-sources with the gate down so the app runs normally (probed: docs-then-app in one process, file/'-e' one-liner/'-e'-alone usage error all behave identically through the new file). punkboot core 0.6.0: new launcher_builtin_docpackages map (script -> app-punkscript-docs); launcher_show_help's built-in arm does a guarded lazy 'package require' of the mapped docs package before the usage query - help-path only, never on boot/dispatch (ready-probe and dispatch untouched). The G-031 registration-model header comment now names the durable doc id and records the app-owned 'package'-key option. Copies synced byte-identical: project-0.1 layout + modpod-template layout. punkexe moduledoc 0.8.0 (single-definer handover): (script)::punkexe::script is no longer defined here - a pointer comment stands in its place and the Overview records the ownership rule (docs live with the owning code: app-owned for app-handled subcommands, this moduledoc for core-owned surfaces like tclsh/buildinfo/help and the top-level dispatch). Single definer verified: loading both sources raises no duplicate-definition (undefine) notices - the handover withdraws the moduledoc entry in the same change-set per the docpackages last-loaded-wins pre-test pin. Durable-doc decision (the acceptance's 'location decided in the work'): the registration definition id (script)::punkboot::registration IS the durable doc for the *_main.tcl declaration keys (summary/argsid/package/parse incl the parse=1 gate, all already documented there); punkboot moduledoc 0.3.1 extends its 'package' key text with the app-owned docs-package pattern (gate shape pointed at src/lib/app-punkscript/pkgIndex.tcl). Kit authors reach it from the core header contract, the punkexe moduledoc Overview and the project_main.tcl worked examples. Help-path load cost measured and recorded (goal file): the app-ownership marginal cost is the guarded docs require - 3.5 ms (inert). The ~396 ms first-render total is the one-time punk::ansi/textblock render-stack load + definition evaluation, incurred identically wherever the definition lives; boot/dispatch cost is zero. Tests: launcherhelp.test 25/25 - 24 existing pins unchanged plus new launcherhelp_appowned_script_docs: the fake-main harness (G-031 shape, no bake) run through the baked kit's tclsh subcommand in SRC package mode, where the source tree serves the nested boot with version precedence - the src moduledoc defines no script id, so the successful tabular render carrying the G-168-era scriptfile help text (line-break-safe markers; the oneliner form's rows are not in the default form-0 table) proves the app-owned lazy resolution; stderr asserted free of 'clearing existing data' notices. Harness lesson recorded: manual tm/auto_path prepends in a fake main are WIPED by the nested boot's path configuration - the src package mode is the correct lever. Full modules/punk/args subtree 337 passed / 3 pre-existing skips / 0 failed on BOTH tclsh90 and tclsh87 - the G-168 punkexemodel.test/formcheck.test pins now load the script id via app-punkscript-docs (src/lib derived from the test file location) and guard the handover shape at its new home. The 10 failures in maketclbakelist.test / maketcllibfetch.test are PRE-EXISTING (reproduced identically at HEAD with this change-set stashed; the G-139 libfetch-test reading is a recorded pending user decision). Degraded/plain path intact (PUNKBOOT_PLAIN pin unchanged; mixed promotion states degrade gracefully by construction). Minted punkexe-0.8.0.tm + punkboot-0.3.1.tm via make.tcl modules. Goals: G-169 entry moved to GOALS-archive.md, detail file to goals/archive/ with mechanism, decisions, measured costs and verification evidence; two open Follow-ons (the coherent-set vfscommonupdate/bake promotion carrying lib/app-punkscript 1.2 + core 0.6.0 + punkexe 0.8.0 together; extending app ownership to shell/punk/shellspy). Reference sweep: G-170's Related line updated (the defs' home now decided - its formhint un-suppression edits both homes). src/lib AGENTS.md app-punkscript bullet + src/tests/modules AGENTS.md punk/args bullet extended. goals_lint clean (81 active / 89 archived). Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
19 changed files with 469 additions and 145 deletions
@ -1,46 +0,0 @@
|
||||
# G-169 App-owned launch-subcommand documentation consumed by the launcher |
||||
|
||||
Status: proposed |
||||
Scope: src/lib/app-punkscript/punkscript.tcl (carries its subcommand's punk::args definition via inert registration); src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm (single-definer handover); src/vfs/_config/punkboot_core.tcl (built-in help resolution via app-owned ids, *_main.tcl declaration surface documented, + synced copies via established channels); src/tests/shell/testsuites/punkexe/launcherhelp.test |
||||
Goal: A subcommand's punk::args definition can live in its handling app and the launcher consumes it - proven on app-punkscript owning (script)::punkexe::script (inert PUNKARGS registration, no load-time side effects, lazily resolved at help/error time) with the moduledoc entry handed over (one definer per id); the ownership rule is recorded (docs live with the owning code - app-owned for app-handled subcommands, moduledoc for core-owned surfaces like tclsh); and the existing *_main.tcl project-subcommand declaration surface (summary/package/argsid/parse) is documented as the official authoring mechanism it already is. |
||||
Acceptance: app-punkscript carries the script definition and 'help script' renders it on a baked kit via lazy resolution (guarded package require + docpackages/argsid - no eager load at boot; help-path load cost measured and recorded); the punkexe moduledoc no longer defines the id (no duplicate-definition warnings; single definer verified); degraded/plain help path intact; the *_main.tcl declaration keys are documented where kit authors look (location decided in the work: core header contract + a durable doc) including the parse=1 gate; launcherhelp.test passes with a new app-owned-resolution pin. |
||||
|
||||
## Context |
||||
|
||||
2026-08-05 discussion: the actual '-e' parsing lives in app-punkscript while its |
||||
documentation lives in the punkexe moduledoc - co-location kills that drift |
||||
class. Nothing structural prevents launcher consumption of app-owned docs: the |
||||
argsid+package indirection and parse=1 gate already exist for project |
||||
subcommands (punkboot_core.tcl:1779-1791, 2168-2192), and punk::args 0.12.7's |
||||
docpackages association loads a documenting package lazily on first usage query. |
||||
The moduledoc pattern remains right where implementation is external or |
||||
core-owned (tclcore precedent: separation + parity pins). |
||||
|
||||
## Notes |
||||
|
||||
- Coordination with G-168 (achieved 2026-08-05 - goals/archive/G-168-selection-sound-launch-definitions.md): |
||||
G-168 landed first, so THIS goal is the one that lands second and edits the |
||||
definitions at their then-current home (never two definers) - the re-homed |
||||
script definition carries G-168's fencing shape (file form scriptfile |
||||
-regexprefail {^-e$} + ./-e message, oneliner '-e' as a required solo flag) |
||||
and any tclsh re-home carries the {^-}/{^[^-]} fences plus the stdin form's |
||||
-overlapallowed {scriptfile} sanction; the punkexemodel.test / |
||||
formcheck.test pins guard the handover. |
||||
- Related: G-075 (proposed) - sibling documentation-reachability surface. |
||||
- Related: G-042/G-043 (proposed) - adjacent declaration-composition patterns; |
||||
deliberate non-overlap (launch surface, not repl subshells). |
||||
- Overlap survey 2026-08-05: app-punkscript intersects no live goals; the |
||||
punkboot_core.tcl matches are the G-168 survey's set (G-089 nearest, others |
||||
incidental). |
||||
- 2026-08-05 pre-test pins (new args-tier docpackages.test, green tclsh90+tcl87): |
||||
registration in ::punk::args::register::NAMESPACES is inert - the next |
||||
update_definitions call id-SCANS the source without evaluating definitions, |
||||
id_exists never triggers loading, and real_id/usage lazily load the |
||||
registered source on the first query naming the documented namespace, |
||||
including tag-prefixed script-level families (the (script)::punkexe::* path |
||||
this goal rides). Duplicate ids resolve last-loaded-wins accompanied only by |
||||
a stderr undefine notice - the engine carries a recorded detect-duplicates |
||||
todo (punk::args update_definitions scan loop) - so the single-definer |
||||
handover must withdraw the moduledoc entry in the same change-set that lands |
||||
app ownership rather than rely on any warning surface |
||||
(docpackages_duplicate_definers_last_registered_wins). |
||||
@ -0,0 +1,153 @@
|
||||
# G-169 App-owned launch-subcommand documentation consumed by the launcher |
||||
|
||||
Status: achieved 2026-08-05 |
||||
Scope: src/lib/app-punkscript/punkscript.tcl (carries its subcommand's punk::args definition via inert registration); src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm (single-definer handover); src/vfs/_config/punkboot_core.tcl (built-in help resolution via app-owned ids, *_main.tcl declaration surface documented, + synced copies via established channels); src/tests/shell/testsuites/punkexe/launcherhelp.test |
||||
Goal: A subcommand's punk::args definition can live in its handling app and the launcher consumes it - proven on app-punkscript owning (script)::punkexe::script (inert PUNKARGS registration, no load-time side effects, lazily resolved at help/error time) with the moduledoc entry handed over (one definer per id); the ownership rule is recorded (docs live with the owning code - app-owned for app-handled subcommands, moduledoc for core-owned surfaces like tclsh); and the existing *_main.tcl project-subcommand declaration surface (summary/package/argsid/parse) is documented as the official authoring mechanism it already is. |
||||
Acceptance: app-punkscript carries the script definition and 'help script' renders it on a baked kit via lazy resolution (guarded package require + docpackages/argsid - no eager load at boot; help-path load cost measured and recorded); the punkexe moduledoc no longer defines the id (no duplicate-definition warnings; single definer verified); degraded/plain help path intact; the *_main.tcl declaration keys are documented where kit authors look (location decided in the work: core header contract + a durable doc) including the parse=1 gate; launcherhelp.test passes with a new app-owned-resolution pin. |
||||
|
||||
## Context |
||||
|
||||
2026-08-05 discussion: the actual '-e' parsing lives in app-punkscript while its |
||||
documentation lives in the punkexe moduledoc - co-location kills that drift |
||||
class. Nothing structural prevents launcher consumption of app-owned docs: the |
||||
argsid+package indirection and parse=1 gate already exist for project |
||||
subcommands (punkboot_core.tcl:1779-1791, 2168-2192), and punk::args 0.12.7's |
||||
docpackages association loads a documenting package lazily on first usage query. |
||||
The moduledoc pattern remains right where implementation is external or |
||||
core-owned (tclcore precedent: separation + parity pins). |
||||
|
||||
## Notes |
||||
|
||||
- Coordination with G-168 (achieved 2026-08-05 - goals/archive/G-168-selection-sound-launch-definitions.md): |
||||
G-168 landed first, so THIS goal is the one that lands second and edits the |
||||
definitions at their then-current home (never two definers) - the re-homed |
||||
script definition carries G-168's fencing shape (file form scriptfile |
||||
-regexprefail {^-e$} + ./-e message, oneliner '-e' as a required solo flag) |
||||
and any tclsh re-home carries the {^-}/{^[^-]} fences plus the stdin form's |
||||
-overlapallowed {scriptfile} sanction; the punkexemodel.test / |
||||
formcheck.test pins guard the handover. |
||||
- Related: G-075 (proposed) - sibling documentation-reachability surface. |
||||
- Related: G-170 (proposed) - back-pointer added at activation 2026-08-05 |
||||
(activation-freshness survey; G-170 already points here): its help-depth |
||||
arms render whatever home this goal gives the definitions, and its |
||||
formhint un-suppression edits them at that home. |
||||
- Related: G-042/G-043 (proposed) - adjacent declaration-composition patterns; |
||||
deliberate non-overlap (launch surface, not repl subshells). |
||||
- Overlap survey 2026-08-05: app-punkscript intersects no live goals; the |
||||
punkboot_core.tcl matches are the G-168 survey's set (G-089 nearest, others |
||||
incidental). |
||||
- 2026-08-05 pre-test pins (new args-tier docpackages.test, green tclsh90+tcl87): |
||||
registration in ::punk::args::register::NAMESPACES is inert - the next |
||||
update_definitions call id-SCANS the source without evaluating definitions, |
||||
id_exists never triggers loading, and real_id/usage lazily load the |
||||
registered source on the first query naming the documented namespace, |
||||
including tag-prefixed script-level families (the (script)::punkexe::* path |
||||
this goal rides). Duplicate ids resolve last-loaded-wins accompanied only by |
||||
a stderr undefine notice - the engine carries a recorded detect-duplicates |
||||
todo (punk::args update_definitions scan loop) - so the single-definer |
||||
handover must withdraw the moduledoc entry in the same change-set that lands |
||||
app ownership rather than rely on any warning surface |
||||
(docpackages_duplicate_definers_last_registered_wins). |
||||
|
||||
## Progress |
||||
|
||||
Achieved 2026-08-05 in one session (user-directed activation and |
||||
implementation same day; app-punkscript 1.2 + app-punkscript-docs 1.2, |
||||
punkexe moduledoc 0.8.0, punkboot moduledoc 0.3.1, punkboot core 0.6.0). |
||||
|
||||
Mechanism landed: |
||||
|
||||
- src/lib/app-punkscript/punkscript.tcl carries the (script)::punkexe::script |
||||
definition (the G-168 selection-sound shape moved VERBATIM - value strings |
||||
byte-identical, so renders match the pre-handover moduledoc) in |
||||
::app::punkscript::argdoc, with an idempotent docs section: a plain |
||||
namespace-variable set plus a membership-guarded lappend to |
||||
::punk::args::register::NAMESPACES - no package requires, no punk::args |
||||
dependency, no definition evaluation (evaluation stays lazy on the first |
||||
query naming the id, per the docpackages pre-test pins). |
||||
- Docs-only loading: pkgIndex.tcl provides package app-punkscript-docs 1.2 |
||||
from the SAME file via an execution gate (::app::punkscript::docs_only set |
||||
around the source; punkscript.tcl returns after the docs section when the |
||||
gate is up, and 'package provide app-punkscript' moves below the gate) - |
||||
requiring the docs NEVER runs a script, and a later |
||||
'package require app-punkscript' re-sources with the gate down so the app |
||||
runs normally (probed: docs-then-app in one process, APPRAN both orders, |
||||
'-e'-alone usage error intact, no duplicate registrations). |
||||
- Launcher consumption: punkboot_core 0.6.0 adds launcher_builtin_docpackages |
||||
(dict: script -> app-punkscript-docs); launcher_show_help's built-in arm |
||||
does a guarded 'package require' of the mapped docs package before the |
||||
usage query - help-path only, never on boot/dispatch (the ready-probe and |
||||
dispatch paths are untouched). Copies synced: project-0.1 layout + |
||||
modpod-template layout byte-identical to the master (the template copy also |
||||
re-synced by make.tcl modules' punkcheck step). |
||||
- Single-definer handover: the punkexe moduledoc (0.8.0) no longer defines |
||||
the id - a pointer comment stands in its place and the Overview records the |
||||
ownership rule (docs live with the owning code: app-owned for app-handled |
||||
subcommands, moduledoc for core-owned surfaces like tclsh/buildinfo/help |
||||
and the top-level dispatch). |
||||
|
||||
Decision - durable-doc location for the *_main.tcl declaration keys (the |
||||
acceptance's 'location decided in the work'): the registration definition id |
||||
(script)::punkboot::registration in the punkboot moduledoc IS the durable |
||||
doc - it already documented all four project_subcommand_info keys |
||||
(summary/argsid/package/parse incl the parse=1 gate) and its 'package' key |
||||
text now also documents the app-owned docs-package pattern (0.3.1, with the |
||||
gate shape pointed at src/lib/app-punkscript/pkgIndex.tcl). The core header |
||||
contract (punkboot_core.tcl G-031 registration-model comment) now names that |
||||
id explicitly and records the app-owned option; worked examples remain in |
||||
the project_main.tcl template (verified present: summary/argsid example |
||||
block). Kit authors reach the durable doc from the core header, the punkexe |
||||
moduledoc Overview, and the template. |
||||
|
||||
Help-path load cost (measured 2026-08-05, tclsh90, src tree): the |
||||
app-ownership marginal cost is the guarded docs require - 3.5 ms (inert: |
||||
namespace-variable set + registration lappend + gate return). The first |
||||
'help script' render measured 396 ms total, dominated by the one-time |
||||
punk::ansi/textblock render-stack load + definition evaluation that occurs |
||||
IDENTICALLY wherever the definition lives - so app ownership adds only the |
||||
~3.5 ms require to the help path, and nothing to boot/dispatch. |
||||
|
||||
Verification evidence: |
||||
|
||||
- launcherhelp.test 25/25: the 24 existing pins unchanged plus the new |
||||
launcherhelp_appowned_script_docs pin - the fake-main harness (G-031 |
||||
shape, no bake) run THROUGH the baked kit's tclsh subcommand in src |
||||
package mode, where the source tree serves the nested boot with version |
||||
precedence: the src moduledoc defines no script id, so the successful |
||||
tabular render carrying the G-168-era scriptfile help text (line-break-safe |
||||
markers) proves app-owned lazy resolution; stderr asserted free of |
||||
duplicate-definition ('clearing existing data') notices. Post-bake the |
||||
kit-internal stack carries the same set and the render is identical. |
||||
(Harness lesson recorded: manual tm/auto_path prepends in a fake main are |
||||
WIPED by the nested boot's path configuration - the src package mode is |
||||
the correct lever, and it resolves the project from the executable's own |
||||
location.) |
||||
- Full modules/punk/args subtree 337 passed / 3 pre-existing skips / 0 |
||||
failed on BOTH tclsh90 and tclsh87 - the G-168 punkexemodel.test / |
||||
formcheck.test pins now load the script id via app-punkscript-docs |
||||
(src/lib derived from the test file location) and guard the handover |
||||
exactly as the G-168 coordination note intended. |
||||
- Src-level probes: moduledoc 0.8.0 loaded first -> id_exists 0 for the |
||||
script id; app-punkscript-docs require -> registered, app NOT run, |
||||
usage renders, forms {file oneliner}, G-168 selections/verdicts/formcheck |
||||
all intact through the app-owned definition; no undefine notices. |
||||
- App parity probes (the restructure must not break the runner): file/'-e' |
||||
one-liner/'-e'-alone-usage-error/docs-then-app sequences all behave |
||||
identically through the new file (src paths; template-provider warnings |
||||
are minimal-path environment noise, absent in kit contexts). |
||||
- shell/testsuites/punkexe subtree: launcherhelp 25/25 and the other |
||||
launcher-adjacent suites green; the 10 failures in maketclbakelist.test / |
||||
maketcllibfetch.test are PRE-EXISTING (reproduced identically at HEAD |
||||
with this change-set stashed; the G-139 libfetch-test reading is a |
||||
recorded pending user decision from the 2026-08-05 follow-on sweep). |
||||
- Minted punkexe-0.8.0.tm + punkboot-0.3.1.tm via make.tcl modules. |
||||
- Degraded/plain path intact: the PUNKBOOT_PLAIN launcherhelp pin passes |
||||
unchanged, and mixed promotion states degrade gracefully by construction |
||||
(old core never requires the docs package and the old moduledoc still |
||||
defines the id; new core + old lib falls to the guarded-require failure |
||||
and the plain summary line). |
||||
|
||||
## Follow-ons |
||||
|
||||
Follow-on: the next vfscommonupdate/bake promotion carries the coherent set together - src/lib/app-punkscript (pkgIndex + punkscript.tcl 1.2), punkboot core 0.6.0 and punkexe moduledoc 0.8.0 (plus punkboot moduledoc 0.3.1) - after which the baked kit serves 'help script' from the app-owned definition in internal mode; mixed intermediate states degrade gracefully as recorded in Progress => open |
||||
Follow-on: extend app ownership to the other app-handled built-ins (shell/punk via app-punkshell, shellspy via app-shellspy) whose moduledoc entries are summary-level passthrough contracts today - same docs-package pattern, launcher_builtin_docpackages gains their entries => open |
||||
@ -1 +1,9 @@
|
||||
package ifneeded app-punkscript 1.1 [list source [file join $dir punkscript.tcl]] |
||||
package ifneeded app-punkscript 1.2 [list source [file join $dir punkscript.tcl]] |
||||
#G-169: docs-only load of the same file - the execution gate in punkscript.tcl |
||||
#returns before the app body, so requiring the docs never runs a script. Used |
||||
#by the launcher's help path (guarded lazy require in punkboot_core.tcl). |
||||
package ifneeded app-punkscript-docs 1.2 [list ::apply {{dir} { |
||||
namespace eval ::app::punkscript {variable docs_only 1} |
||||
source [file join $dir punkscript.tcl] |
||||
namespace eval ::app::punkscript {variable docs_only 0} |
||||
}} $dir] |
||||
|
||||
@ -1,6 +1,7 @@
|
||||
0.3.0 |
||||
0.3.1 |
||||
#First line must be a semantic version number |
||||
#all other lines are ignored. |
||||
#0.3.1 - documentation-only (G-169): the registration definition's 'package' key text now documents the app-owned docs-package pattern (an execution-gated source of the app's own file, so a subcommand's definition lives beside its parsing code and the help path never runs the app - the app-punkscript-docs precedent for the built-in 'script' subcommand, with the gate shape in src/lib/app-punkscript/pkgIndex.tcl). This registration definition is the recorded durable-doc location for the *_main.tcl declaration keys (summary/argsid/package/parse incl the parse=1 gate), alongside the punkboot_core.tcl header contract and the project_main.tcl worked examples. |
||||
#0.3.0 - single-mechanism revision (2026-08-05, user direction): help-flag interception withdrawn from the launcher - registration argsid text now names 'help <name>' as the only launcher-rendered route (apps own their -help handling); unknownfirst text covers the G-077 '-e' one-liner and states help flags are never intercepted |
||||
#0.2.0 - G-032 registration surface extension documented: project_subcommand_info (summary/argsid/package/parse) in the registration definition + thin-main obligations; built-in list gains help; launcher help/flag semantics (unknownfirst=script gate, argsid-gated -help interception) recorded |
||||
#0.1.0 - initial (G-031 runtime-queryable boot-core API doc): (script)::punkboot overview + thin-main obligations, (script)::punkboot::registration (project_subcommands / launch_defaults), live definitions for the persistent ::punkboot procs (zipfs_mount_pairs, zipfs_kit_mountbase, path_within, proj_root_find); boot_state surface documented |
||||
|
||||
Loading…
Reference in new issue