Browse Source

punk::libunknown 0.1 -> 0.2.0: adopt major.minor.patch + manual-versioning guidance

Verified nothing depends on the old version or filename before renaming:
all 'package require punk::libunknown' sites are unversioned; punk_main.tcl
and punk::repl locate the module by globbing libunknown-*.tm and picking the
highest by vcompare (so the renamed dev copy now also outversions the stale
bootsupport and project.vfs 0.1 copies deterministically, instead of relying
on tm path order for a same-version tie); bootsupport's
include_modules.config lists it by name only.

The 0.2.0 number retroactively versions the two changes shipped against the
0.1 filename earlier today (register_all_tm deep discovery - a minor API
addition - and the source_pkgindex sourcing-scope fix). A version-history
comment block in the module header now substitutes for the buildversion.txt
changelog other modules carry.

src/modules/AGENTS.md: the punk::libunknown exception bullets now spell out
the manual-versioning mechanics for agents - same Patch/Minor/Major bump
rules as buildversion-tracked modules, executed as a file rename plus Meta
line, manpage_begin, provide-block and version-history updates, with a
check for exact-version/filename dependents before any first bump.

discovery.test/libsearch.test: the source-tree libunknown locator now picks
the highest libunknown-*.tm by vcompare instead of plain lsort (robust to
future version bumps). Verified live in punk902z src: package provide
reports 0.2.0, register_all_tm present, lib.search deep discovery intact.
Suites green under tclsh90 and tclsh87. Build artifacts synced (root
modules/ and _vfscommon.vfs carry only libunknown-0.2.0.tm).

punkshell 0.10.2. Stale 0.1 copies remain in src/bootsupport/modules
(pending 'make.tcl bootsupport') and src/vfs/project.vfs (pending layout
maintenance) - both now cleanly outversioned at runtime.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 4 days ago
parent
commit
3970b8e695
  1. 4
      CHANGELOG.md
  2. 2
      punkproject.toml
  3. 4
      src/modules/AGENTS.md
  4. 23
      src/modules/punk/libunknown-0.2.0.tm
  5. 20
      src/tests/modules/punk/libunknown/testsuites/discovery/discovery.test
  6. 21
      src/tests/modules/punk/mix/testsuites/loadedlib/libsearch.test
  7. 23
      src/vfs/_vfscommon.vfs/modules/punk/libunknown-0.2.0.tm

4
CHANGELOG.md

@ -5,6 +5,10 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to
Entries are newest-first; one bullet per notable change. See the root `AGENTS.md`
"Project Versioning" section for the bump policy.
## [0.10.2] - 2026-07-11
- punk::libunknown bumped 0.1 → 0.2.0 (file renamed `libunknown-0.2.0.tm`), retroactively versioning the register_all_tm and source_pkgindex additions and adopting full `major.minor.patch` form. Verified nothing requires it by exact version or filename: punk_main.tcl and punk::repl glob `libunknown-*.tm` picking the highest by vcompare (the dev copy now also outversions the stale bootsupport/project.vfs `0.1` copies deterministically), bootsupport's include_modules.config lists it by name only. The module header now carries a version-history block in lieu of a buildversion.txt, and `src/modules/AGENTS.md` documents the manual-versioning bump mechanics for agents (same Patch/Minor/Major rules as buildversion-tracked modules).
## [0.10.1] - 2026-07-11
- punk::libunknown: pkgIndex.tcl scripts are now executed in an isolated `source_pkgindex` frame providing the documented `$dir` variable plus `auto_path`/`env` global links (matching stock tclPkgUnknown's contract), instead of at `::` scope with a `global dir`. Fixes any user global named `dir` being silently overwritten whenever a `package require` fell through to the pkg unknown handler, and stops index scripts' helper variables (`ver`, `pkg`, `script`, `_CawtSubDirs`, ...) leaking into the global namespace. Verified against tcllib 2.0's index behaviours (auto_path extension, apply-scoped subindex sweep, critcl-style loaders); regression tests pin the `$dir`/auto_path/no-leak contract.

2
punkproject.toml

@ -1,3 +1,3 @@
[project]
name = "punkshell"
version = "0.10.1"
version = "0.10.2"

4
src/modules/AGENTS.md

@ -15,7 +15,7 @@ Source of truth for all editable Punk project modules. This is where agents shou
- Module filenames use the literal suffix `-999999.0a1.0.tm`.
- Corresponding `<modulename>-buildversion.txt` files hold the real version number.
- The exception is `punk::libunknown`, which uses its own version `0.1`.
- The exception is `punk::libunknown`, which is manually versioned: its real `major.minor.patch` version lives in the filename (`libunknown-<version>.tm`) and there is no buildversion.txt. The same bump rules apply as for buildversion-tracked modules (see "Versioning And Releases"); the mechanics differ — see the manual-versioning bullet there.
- `#modpod-*` directories contain internal files packed into `.tm` archives during build; do not flatten or edit them without understanding the modpod format.
- `_build/` directory holds build intermediates and should not be manually edited.
- Always declare dependencies explicitly using `package require <name>` near file tops.
@ -321,7 +321,7 @@ return
This keeps the changelog discoverable alongside the version number without requiring a separate CHANGES file.
- **Bootstrap-tracked files only**`punkcheck-buildversion.txt`, `punk/repo-buildversion.txt`, `punk/mix-buildversion.txt` (the top-level `punk::mix` file only; `punk::mix::util`, `punk::mix::cli`, and `punk/mix/commandset/*` version independently and are not covered by this check), and `punk/tdl-buildversion.txt`: bump at least **minor** whenever a call site inside that file is updated to use a new API, even if the file's own interface is unchanged. `src/make.tcl` reads only these four files to classify bootsupport staleness (major=abort, minor=prompt, patch=silent-proceed); under-bumping one of them to patch when the call-site change is more significant causes `make.tcl` to mis-classify and either wrongly proceed without prompting or wrongly abort. See `src/bootsupport/AGENTS.md` "Bootsupport Staleness Handling" for the full contract.
- **All other modules** (including `punk::mix` submodules): call-site updates follow ordinary judgement from the Patch/Minor/Major rules above — a behavior-preserving call-site change is a patch (or no bump if genuinely a no-op); reserve minor for changes that add capability to the module's *own* API. `src/make.tcl` does not read these versions, so there is no automated consequence, but keep the changelog accurate since it is the only record of the module's real semantic version.
- There may be occasional exceptions such as `punk::libunknown-0.1.tm`, which is deliberately manually versioned; new modules should use the magic version mechanism.
- **Manually versioned modules** (currently only `punk::libunknown`): the real `major.minor.patch` version is the filename suffix and the `package provide` block value; there is no `<name>-buildversion.txt` and the build does not stamp a version. The Patch/Minor/Major bump rules above apply identically — an agent changing such a module bumps by (1) renaming the file (`git mv`) to the new version, (2) updating the `# Application <name> <version>` Meta line, the doctools `manpage_begin` version and the provide-block `set version`, and (3) appending a changelog comment line to the version-history block in the module header (it substitutes for the buildversion.txt changelog). Before the first bump of such a module, verify nothing requires it by exact version or hardcoded filename (for punk::libunknown: punk_main.tcl and punk::repl glob `libunknown-*.tm` and pick the highest by vcompare, bootsupport's include_modules.config lists it by name only, and all requires are unversioned - verified 2026-07-11). New modules should use the magic version mechanism instead.
- Modules with the magic version number must not appear in output paths such as `<projectdir>/modules`.
- When referencing ranges, use bounded specs such as `1.2.3-2.0.0`.
- Convert loose versions to bounded form in module metadata; helper utilities exist in boot modules for this purpose.

23
src/modules/punk/libunknown-0.1.tm → src/modules/punk/libunknown-0.2.0.tm

@ -7,17 +7,34 @@
# (C) 2025
#
# @@ Meta Begin
# Application punk::libunknown 0.1
# Application punk::libunknown 0.2.0
# Meta platform tcl
# Meta license MIT
# @@ Meta End
#
# Version history (manually versioned module - the real version lives in the
# filename and the 'package provide' block at the bottom; there is no
# <name>-buildversion.txt. Apply the standard Patch/Minor/Major bump rules
# from src/modules/AGENTS.md "Versioning And Releases" - bumping means
# renaming the file AND updating the Meta line above, the manpage_begin line
# below and the provide-block version, then appending a line here):
#0.2.0 - register_all_tm: deep discovery proc registering ifneeded scripts for
# .tm modules at every namespace depth (once per tm epoch, interp-local
# tm_fullscan guard); used by 'dev lib.search' by default
#0.2.0 - source_pkgindex: pkgIndex.tcl scripts execute in an isolated frame
# ($dir formal + auto_path/env global links) instead of at :: scope -
# user global 'dir' no longer clobbered, index helper vars no longer
# leak into the global namespace ('global dir' removed from
# zipfs_tclPkgUnknown)
#0.1 - initial: epoch-based zipfs_tm_UnknownHandler/zipfs_tclPkgUnknown
# package unknown chain, 'package epoch' command, controlled forget
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin punkshell_module_punk::libunknown 0 0.1]
#[manpage_begin punkshell_module_punk::libunknown 0 0.2.0]
#[copyright "2025"]
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}]
#[moddesc {-}] [comment {-- Description at end of page heading --}]
@ -2102,7 +2119,7 @@ namespace eval ::punk::args::register {
package provide punk::libunknown [tcl::namespace::eval ::punk::libunknown {
variable pkg punk::libunknown
variable version
set version 0.1
set version 0.2.0
}]
return

20
src/tests/modules/punk/libunknown/testsuites/discovery/discovery.test

@ -117,17 +117,21 @@ namespace eval ::testspace {
}
#The SOURCE-TREE punk::libunknown, located relative to this test file.
#A 'package require punk::libunknown' would tie-break the same-version (0.1)
#copies in src/modules and src/bootsupport/modules by tm path order - in the
#testinterp that order deliberately favours bootsupport, and in a child interp
#it depends on machine-specific env tm paths. These tests must exercise the
#source copy, so it is sourced directly by path (as punk_main.tcl loads it).
#A 'package require punk::libunknown' could resolve to another copy (e.g
#bootsupport) depending on tm path order - in the testinterp that order
#deliberately favours bootsupport, and in a child interp it depends on
#machine-specific env tm paths. These tests must exercise the source copy,
#so it is sourced directly by path (as punk_main.tcl loads it), picking the
#highest version by vcompare should multiple libunknown-*.tm coexist.
variable libunknown_src ""
variable script_dir [file dirname [file normalize [info script]]]
set srcmodules [file normalize [file join $script_dir .. .. .. .. .. .. modules]]
set candidates [lsort [glob -nocomplain [file join $srcmodules punk libunknown-*.tm]]]
if {[llength $candidates]} {
set libunknown_src [lindex $candidates end]
foreach candidate [glob -nocomplain [file join $srcmodules punk libunknown-*.tm]] {
set thisver [file rootname [lindex [split [file tail $candidate] -] 1]]
if {$libunknown_src eq "" || [package vcompare $thisver $libunknown_ver] == 1} {
set libunknown_src $candidate
set libunknown_ver $thisver
}
}
testConstraint libunknownavailable [expr {$libunknown_src ne ""}]
if {$libunknown_src eq ""} {

21
src/tests/modules/punk/mix/testsuites/loadedlib/libsearch.test

@ -77,18 +77,21 @@ namespace eval ::testspace {
# searches and -refresh walks are deterministic and fast.
# -------------------------------------------------------------------------
#The SOURCE-TREE punk::libunknown, located relative to this test file.
#A 'package require punk::libunknown' would tie-break the same-version (0.1)
#copies in src/modules and src/bootsupport/modules by tm path order - these
#tests need register_all_tm from the source copy, so it is sourced directly
#by path (as punk_main.tcl loads it). The other punk requires below are dev
#alpha versions (999999.0a1.0), which 'package prefer latest' selects
#deterministically regardless of tm path order.
#A 'package require punk::libunknown' could resolve to another copy (e.g
#bootsupport) depending on version/tm path order - these tests need
#register_all_tm from the source copy, so it is sourced directly by path
#(as punk_main.tcl loads it), picking the highest version by vcompare.
#The other punk requires below are dev alpha versions (999999.0a1.0), which
#'package prefer latest' selects deterministically regardless of path order.
variable libunknown_src ""
variable script_dir [file dirname [file normalize [info script]]]
set srcmodules [file normalize [file join $script_dir .. .. .. .. .. .. modules]]
set candidates [lsort [glob -nocomplain [file join $srcmodules punk libunknown-*.tm]]]
if {[llength $candidates]} {
set libunknown_src [lindex $candidates end]
foreach candidate [glob -nocomplain [file join $srcmodules punk libunknown-*.tm]] {
set thisver [file rootname [lindex [split [file tail $candidate] -] 1]]
if {$libunknown_src eq "" || [package vcompare $thisver $libunknown_ver] == 1} {
set libunknown_src $candidate
set libunknown_ver $thisver
}
}
variable child ""

23
src/vfs/_vfscommon.vfs/modules/punk/libunknown-0.1.tm → src/vfs/_vfscommon.vfs/modules/punk/libunknown-0.2.0.tm

@ -7,17 +7,34 @@
# (C) 2025
#
# @@ Meta Begin
# Application punk::libunknown 0.1
# Application punk::libunknown 0.2.0
# Meta platform tcl
# Meta license MIT
# @@ Meta End
#
# Version history (manually versioned module - the real version lives in the
# filename and the 'package provide' block at the bottom; there is no
# <name>-buildversion.txt. Apply the standard Patch/Minor/Major bump rules
# from src/modules/AGENTS.md "Versioning And Releases" - bumping means
# renaming the file AND updating the Meta line above, the manpage_begin line
# below and the provide-block version, then appending a line here):
#0.2.0 - register_all_tm: deep discovery proc registering ifneeded scripts for
# .tm modules at every namespace depth (once per tm epoch, interp-local
# tm_fullscan guard); used by 'dev lib.search' by default
#0.2.0 - source_pkgindex: pkgIndex.tcl scripts execute in an isolated frame
# ($dir formal + auto_path/env global links) instead of at :: scope -
# user global 'dir' no longer clobbered, index helper vars no longer
# leak into the global namespace ('global dir' removed from
# zipfs_tclPkgUnknown)
#0.1 - initial: epoch-based zipfs_tm_UnknownHandler/zipfs_tclPkgUnknown
# package unknown chain, 'package epoch' command, controlled forget
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin punkshell_module_punk::libunknown 0 0.1]
#[manpage_begin punkshell_module_punk::libunknown 0 0.2.0]
#[copyright "2025"]
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}]
#[moddesc {-}] [comment {-- Description at end of page heading --}]
@ -2102,7 +2119,7 @@ namespace eval ::punk::args::register {
package provide punk::libunknown [tcl::namespace::eval ::punk::libunknown {
variable pkg punk::libunknown
variable version
set version 0.1
set version 0.2.0
}]
return
Loading…
Cancel
Save