# G-109 libunknown manifest-declared multi-name discovery for zip-based .tm modules Status: proposed Scope: src/modules/punk/libunknown-0.2.1.tm (scan/registration), modpod (manifest emission + load stub; canonical source c:/repo/jn/tclmodules/modpod, vendored copies as consumed), src/modules/punk/mix/ (modpod wrap tooling as touched), src/tests/modules/punk/libunknown/ (new suites + scan-performance characterization) Goal: a zip-based .tm (modpod) can declare additional package-require names - case variants (Thread/thread) and sub-packages - in a manifest at a well-known internal location, and punkshell's libunknown discovers those declarations during module scanning and registers them so package require of ANY declared name loads the single .tm file; real-disk scan performance is preserved: libunknown exists to fix slow-drive/large-multi-path-tree scan cost, so with manifest support enabled the worst-case target is parity with plain tclsh's builtin tm handler on the same tree (zipfs trees remain the fast path). Acceptance: a demonstration modpod .tm declaring a case-variant name and a sub-package name resolves via package require of each declared name on the tcl9 kit (8.6 covered, or its limitation recorded per G-034), from both a real-disk module path and a zipfs module path; the manifest location and format are documented and emitted by the modpod wrap tooling; plain-tclsh behaviour is documented prominently (the filename-derived name loads anywhere zipfs exists; extra names are punkshell/libunknown-only); a scan-performance characterization test compares libunknown-with-manifest-support against plain tclsh's builtin handler over a generated large multi-path real-disk tree and records the numbers in this file showing no worse than parity; extensive suites under src/tests/modules/punk/libunknown/ cover registration, case-variant and sub-package loading, refresh/epoch staleness, and the no-manifest fast path. ## Context Drafted 2026-07-21 from the modpod binary-.tm characterization session (see G-066 Notes for the characterization: self-mounting zip .tm verified working, including nested inside a kit's zipfs; the multi-name mechanism was identified there as NOT YET IMPLEMENTED and split out to this goal at user request). Why multi-name: a single-file binary-bearing .tm can only advertise the one package name its filename encodes under plain tm scanning. Case variants (thread's dll provides both 'Thread' and 'thread') would otherwise need the .tm duplicated per name - wasteful and drift-prone - and a library shipping sub-packages (foo, foo::bar) cannot expose them from one file at all. A manifest at a well-known internal location, read at scan time by punkshell's libunknown, lets one .tm register every name it provides. Accepted trade (user 2026-07-21): multi-name .tm are punkshell/libunknown-only - plain tclsh will not discover the extra names (it has no manifest reader). That is acceptable PROVIDED repo docs indicate it clearly. TIP 590 ('recommend lowercase package names') makes the single-lowercase-name modpod the plain-tclsh-loadable happy path (the self-mount stub needs only zipfs); the manifest mechanism is for when one require name is not enough. New/complex mechanisms are acceptable in punkshell IFF backed by extensive tests (user bar, same session). Performance frame (user 2026-07-21): libunknown was designed to avoid performance problems that primarily occurred on a machine with slower drives and large os-level package paths (multiple tm paths, many packages). Scanning zipfs trees is much faster; real-disk scans must stay performant. Worst-case target: parity with plain tclsh's builtin tm handler on the same tree. Design consequences to settle in the work: - reading a manifest inside a zip .tm without mounting/extracting every candidate: zip end-of-central-directory tail read vs zipfs mount per file; gate the read to modpod-recognizable files (the stub prefix is detectable) so plain .tm files cost nothing extra; - cache manifest results keyed by file identity (mtime/size) under the existing libunknown epoch/refresh machinery (lib.search -refresh semantics) so repeat scans skip re-reads; - registration shape: package ifneeded entries for each declared name mapping to the one .tm (source it - the stub self-mounts and provides). Relationships: G-066 (modpod generation + embedded metadata - the manifest may share its schema/datafile), G-067 (punkbin publish of these artifacts), G-035 (mixed .tm/pkgIndex provision characterization), G-034 (8.6 modpod mount path - the 8.6 leg of acceptance), TIP 590 (lowercase naming), G-110 (the binary inside the .tm loads via the extraction path investigated there). ## Notes - 2026-07-21: drafted and approved (user: "approved - apply both").