Tree:
eedcd57ad2
master
v0.1a
${ noResults }
128 Commits (eedcd57ad23811c78f31830a272095b43706ada1)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
232f2f6096 |
contextual sweep: deprecated make.tcl subcommand references (user-directed, incl. contract lines)
Each site read in context, not grep-replaced; bakehouse vs bake chosen per meaning, and missing invocation arguments supplied where the reference describes an unattended flow: - G-005 Approach + Notes, G-006 Acceptance + body: 'make.tcl project' -> 'make.tcl bakehouse' (the full consumer build these goals integrate with; no flags - conceptual references on a clean checkout, not recipes). - G-057 Acceptance: 'make.tcl project' -> 'make.tcl bake' (icon embedding lives in the kit-wrap stage and must hold for a bare bake; bakehouse inherits). - G-028 Context DELIBERATELY UNCHANGED: dated 2026-07-07 incident narrative - the command actually run; history stays verbatim (alias keeps it readable). - src/runtime/mapvfs.config todo: 'vfs' -> 'bake' wish, re-annotated - G-104 achieved WITHOUT the single-kit-by-name/list-kits item (still open). - src/runtime/vendorlib_vfs.toml header: vfslibs now runs as a phase of bake (G-112 fold), not 'as part of project'. - shellexit.test + staticruntime.test rebuild comments: 'project' -> 'bake' AND stale '(interactive y confirmation)' / bare vfscommonupdate corrected to '-confirm 0' (piped y retired since G-030) - the missing-arguments class. - punk.project layout store vfs READMEs (lib + modules): 'make.tcl vfs' -> 'make.tcl bake'; modpod template twins propagated via the punkcheck layout->modpod sync (make.tcl modules run), never hand-edited. Variant-phrasing sweep confirmed non-hits: G-115 '(vfs assembly)' names the src/vfs payload tier (name retained), G-047 'make.tcl/project.new' is the dev project.new command. Archive tier + CHANGELOG history untouched. goals_lint + goals_xref refs clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
5 days ago |
|
|
a949414bf8 |
make.tcl window doc sweep: bake/bakehouse vocabulary across workflow references
Root README, src/README, src/AGENTS.md (full-build guidance, provenance command list incl. bakehouse's default-on dirty gate, punk-exe-hosted builds, verification), src/modules + src/lib + src/vfs + src/tests + src/tests/shell + src/runtime AGENTS.md workflow references, and the rebuild-instruction comments in scriptexec.test/tclshcmd.test. G-104's G-058 mention gains its archive marker. Historical CHANGELOG entries untouched; goal-file contract texts (G-005/G-006/G-057 Acceptance mention 'make.tcl project') left for proposal-first user approval - the deprecated alias keeps them executable. Layout make.tcl copies are punkcheck-synced build outputs - they refresh via the normal sync channels in the acceptance build, never hand-edited. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
5 days ago |
|
|
e03ce1d64a |
G-113: make.tcl terminal-aware colour policy (tty probe, force overrides, zero-ESC piped)
Startup policy: NO_COLOR > PUNK_FORCE_COLOR/FORCE_COLOR > stdout -winsize tty probe (Tcl 8.7+/9); Tcl 8.6 fails OFF. Piped/unknown non-forced runs push an ansistrip transform on stdout+stderr - zero ESC bytes from every emitter incl. module-side (punk::ansi's colour_disabled deliberately keeps non-colour effects; design finding recorded in the goal file). shell pops the transform. sgr_cache cleared for punk-exe-hosted pre-loaded interps per the punk::ansi contract. define_global_ansi fully gated; raw-SGR literals routed through new ::punkboot::sgr gate (fixes a malformed \x1b\31m). check reports the policy. make.tcl converted CRLF->LF. Verified: tclsh90 + punk91 kit piped zero-ESC (check/help/workflow/modules); force overrides re-colour piped output; NO_COLOR always suppresses colour; 8.6 tcl86-plain; real Windows console mode=tty (hidden-console evidence); WSL pty mode=tty vs piped-plain (tclkit-902-Linux64). New suite punkexe/maketclcolour.test 3/3. src/AGENTS.md bullet revised; punkshell 0.22.2. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
5 days ago |
|
|
19c63ac60e |
punk-runtime list -remote identity columns (G-119 follow-on, user-directed)
The starred active row previously never changed across 'use' switches (every -rN materializes to the same working name) and carried the name-keyed dead end '(not listed on server)' - true of the name, unexplanatory for a working copy whose bytes match a server artifact. Rows the server listing does not name now carry an untitled identity middle column: from=<artifact> for materialized working copies (the beside-toml source; content verified against that artifact's server sha1 so the Remote cell shows a real status - Same version, CONTENT DIFFERS for the immutable-artifact anomaly, or '(artifact not listed on server)'), sha1=<name> for tomlless byte-copies (default-first- then-ordinal pick, the same rule as the freshness fallback so row identity and freshness verdict always name the same artifact). '(not listed on server)' remains only for genuinely unknown files; the (server default) row annotation follows artifact identity onto working copies of the default. Table header/rules widened to the three-column layout, payload row formats now column-aligned across ps1/bash; help text updated; bin/punk-runtime.cmd rewrapped (checkfile clean). Chosen shape (user-approved from mockup variants): untitled middle column with self-keyed from=/sha1= tags - consistent with the plain list metadata summary's from= vocabulary and self-describing when a row is pasted without its header. runtimecmd_freshness.test +3 row-shape tests (identity columns, the identity-following default annotation, anomaly statuses) with ps1/bash parity: 10/10 pass; scriptwrap + binscripts battery 35 pass / 1 pre-existing skip / 0 fail (roundtrip + checkfile pins green, WSL row pins unaffected). bin/AGENTS.md + shell tests AGENTS updated. punkshell 0.22.0. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
6 days ago |
|
|
f562d13d2e |
G-119: punk-runtime freshness verdict - active vs server default (both payloads)
list -remote now states the relationship between the ACTIVE runtime and the SERVER DEFAULT whenever both are known: explicit freshness: AHEAD/ BEHIND verdicts naming both revisions (BEHIND adds a fetch+use update guidance line), an equivalent current verdict where the (= server default) identity annotation did not fire, a different-series incomparable note, and a stated no-revision-basis note for pre-family actives - with sha1 VALUE-matching against the server sha1sums identifying a byte-copy of a server artifact by content (support-file rows excluded; first ordinal/C-collation match in both payloads). A NO-NAME fetch prints the same verdict as a one-line note when the active diverges from the resolved default (BEHIND carries an inline 'use <default>' hint - the artifact was just fetched). Revision basis: -r<N> parsed from artifact-named actives, else the beside-toml revision field (materialized working copies); the default's revision parses from its defaults.txt name. Verdict lines are byte-identical across the payloads; guidance lines keep each payload's program-name convention. Help text (list/fetch sections) mentions the new surface; bin/punk-runtime.cmd rewrapped (checkfile clean, no spacer resize). New fixture-server suite shell/testsuites/binscripts/runtimecmd_freshness.test: a child-process http file server (new src/tests/testsupport/httpfixture.tcl) serves a crafted punkbin layout behind the PUNKBIN_URL override; the ps1 payload runs as the staged committed .cmd via cmd.exe (wrap-pinned path), the bash payload directly under a probed msys/git bash (on windows the polyglot routes unix shells to the powershell payload; WSL bash rejected - WSL2 cannot reach a 127.0.0.1 fixture server). Covers the five G-119 acceptance scenarios with per-scenario ps1/bash verdict-line parity plus bash-side extras (different-series incomparable, fetch-mode BEHIND hint): 7/7 pass; scriptwrap + binscripts subtrees 32 pass / 1 pre-existing skip / 0 fail (roundtrip, checkfile, WSL, dtplite unaffected). bin/AGENTS.md runtime-manager contract records the verdict surface; src/tests + src/tests/shell AGENTS docs cover the new suite and helper. punkshell 0.21.0 + CHANGELOG entry. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
6 days ago |
|
|
83d2c6f44c |
G-118 item 11: env-gated hidden-console test for the dorepl console-reopen path
New src/tests/testsupport/consoleinject.ps1: the G-106 recipe's injection half as a committed helper - FreeConsole/AttachConsole to a target pid's console, open CONIN$, type lines as WriteConsoleInput key events. tclshcmd.test: constraint punkconsole (windows + PUNK_TEST_CONSOLE=1; normal runs skip) gates two tests driving the reopen path end-to-end in the child's OWN hidden console (outer Start-Process -WindowStyle Hidden wrapper owns a fresh console; wrapper runs '<kit> tclsh' there with std handles redirected to files; piped code sets dorepl; injected lines + exit 0 finish it). Pinned: reopened flips 0 -> 1 at reopen with istty immutable at 0, inputbuffer published empty, reopen notice silent by default and STDERR-only under TCLSH_PIPEREPL_DEBUG=1, injected exit completes with code 0 - closing the item-1/7 console-side residue. Deadlines + wrapper-tree kill keep the tests hang-proof; the piped-harness HANG RULE stands for everything else. Verified: PUNK_TEST_CONSOLE=1 run 21/21 against punk9_beta; normal run 19 pass + 2 console skips; shell/*** suite 64 pass / 4 skips / 0 fail. AGENTS updates: src/tests/shell (tclshcmd bullet - coverage now exists, refined hang rule), src/tests (testsupport index + .ps1 helpers wording). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
6 days ago |
|
|
a015ada542 |
G-117 achieved: flip, archive, reference sweep; reopened pin; G-118 items 1+7 verified
Acceptance evidence in the archived detail file: embed verified in all three family members (family_check), sidecar derived from embed with identical build_id, 'info' identifies sidecar-paired/renamed-stray/pre-v1 files without execution and flags doctored-sidecar disagreements, punkbin AGENTS.md schema docs, roundtrip pin green, record survives make.tcl kit wrapping (punk9_beta reads its runtime's r2 record in-kit), r2 re-emitted with full v1 records. Sweep: achieved markers in G-025/G-057/G-108/G-116/G-118/G-119 (G-025's survival expectation updated to confirmed). tclshcmd.test pins ::tclsh(reopened) publication on the rebuilt patched kits (G-118 items 1+7 landed+verified; Progress updated). build905.zig: packager git-identity leg judges success by output not out_code (resolved 'unrecorded' on this host - effective at next emission). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
7 days ago |
|
|
17250a8c97 |
tclsh subcommand G-118 items 3/4/5/9: argv0 stock parity, clean not-found, console fail-fast, project_main parity (0.20.0)
- no-script forms set ::argv0 to the executable path (was the kit boot script) - missing script file: file-exists pre-check, clean message, exit 1 (existing-file source errors keep their full trace) - no piperepl machinery (unpatched runtime or TCLSH_PIPEREPL=0): terminal stdin fails fast with usage guidance (app-punkscript probe) instead of blocking in a raw read; piped degraded eval unchanged; patch-missing notice now 'note:' and a deliberate TCLSH_PIPEREPL=0 opt-out is quiet (old debug lines deleted) - project_main.tcl mirrors the full tclsh dispatch (script-arg/dash/-encoding/ lib: forms; was single-arg-only with stale gate default 0); layout _config copies byte-synced (interim duplication pending G-031) - tclshcmd.test 17 -> 19 (tclsh_noscript_argv0, tclsh_script_notfound); shell subtree 64 pass / 2 goal-gated skips / 0 fail against rebuilt kits Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
7 days ago |
|
|
f3a9067cbf |
runtimebash_wsl.test: tolerate G-103 metadata-era list row format (stale glob)
Local 'list' rows are column-padded '* <name %-35s> (active) <metadata>' since 61cf903d; the test's single-space '* fakert_beta (active)' glob predates that and failed. Assertion intent unchanged: the row is starred AND active-marked. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
e61411c19a |
tclsh subcommand review: tclshcmd.test suite + contract doc corrections
- new punkexe suite (17 tests): dispatch contract (script-arg argv0/argv/ info-script state, honest exit codes, piped no-arg eval, stock arg forms, lib: refusal) plus the piperepl launch-state contract on patched kits (istty/dorepl/evalinput published, piped script-arg state all-zero, unconsumed-piped-input safety default, evalinput opt-in ordering, script consuming stdin itself) and the unpatched degraded-mode notice - hang rule baked in: no test or fixture may set ::tclsh(dorepl) (the console-reopen path blocks under a piped harness; G-106-recipe territory) - patched-kit resolution: env PUNK_PIPEREPL_TEST_EXE, else the punkexe if it probes patched, else bin/punk9_beta.exe / punk9bi_beta.exe - encoding coverage is byte-level (utf-8 vs iso8859-1 fixture; [format %c 233] keeps the .test file pure ascii, runner-encoding-proof) - patches/README.md: corrected the tcl_interactive divergence note (console script-arg runs READ 1 where stock reads 0 - piped launches identical; the early link stays load-bearing for the piped prompt opt-in) and recorded the '? reopen stdin from console' stdout residue as known - shell/AGENTS.md: tclshcmd bullet; stale runtime.bash names corrected to punk-runtime.bash/punk-runtime.cmd Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
168a98d85f |
G-106: powershell console-mode fallback overhaul - punk::console 0.8.0, canonical server script, tests (project 0.17.8)
Raw mode on twapi-less windows runtimes made dependable and quiet: lazy singleton server (tsv-shared per process, spawn no longer at module load), parent-pid self-reaping (no orphan pwsh), the 20s keepalive-without-pinger and the first-message listener kill (reader Close disposing the pipe stream) both fixed, disableraw served on no-inputmode runtimes (8.6 path), enable confirmed via live tcl9 -inputmode before return, script resolution env -> argv0 -> module-dir -> embedded copy (pwd fallback gone; kits need no scriptlib on disk). PUNK_PS_CONSOLEMODE_DEBUG=1 for diagnostics both sides. scriptlib/utils/pwsh reconciled: canonical consolemode_server_async.ps1 rewritten (protocol enableraw|disableraw|ping|exit, parent-pid watch, posh-git MIT attribution for the C# snippet), five experiment variants retired (consolemode_server.ps1, *_async1.ps1, *_async.2ps1, consolemode.ps1, consolemode_enableraw.ps1), README labels the folder. New console suite psfallback.test pins the embedded-copy/file sync and the resolution chain. punk::repl stale comment fix (no behaviour change). Verified per the recipe recorded in the goal detail file: hidden-console selftests on suite tclsh90spr + zipfs kit tclsh90sprzip (25s-idle survival, stop/respawn, zero orphans), live make.tcl-shell and bare-repl sessions driven by injected keystrokes (console mode 0x1E7<->0x1E1 read externally), embedded-resolution forced run, console testsuite 76/76. G-106 acceptance met - achieved flip recorded in the detail file; archive move follows in the next commit. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
0eda40af32 |
runtests: version-floor the runner's requires (fossilized-kit rejection); concurrency child floor
Root cause of the punk86-kit runtests failure: a punk-kit interpreter's
boot pre-registers its kit-stamped package versions, and an unversioned
require satisfiable by such a registration never fires package unknown -
the freshly-added bootsupport tm path is never scanned. The old kit's
punk::args 0.1.0 won the require, then the versioned punk::path 0.4.0-
pulled a modern module whose load-time argdoc needs punk::args::define:
invalid command name.
Floors added: punk::args 0.12- (runtests.tcl toplevel), punk::lib
0.5.1- (both 8.6 lpop guards; punk::path 0.4.0- already floored in
discovery.tcl). Feature-era minimums, not latest pins - their purpose is
rejecting fossils so package unknown resolves the bootsupport copy.
Verified: the floors alone resurrect even the OLD fossilized punk86 kit
(discover-only + a 35/35 suite run); native 9 and 8.6 unaffected.
concurrency.test child preamble floors its punkcheck require (0.6-):
kit-hosted children boot with kit-stamped punkcheck PRELOADED, and a
stale kit (pre-vfscommonupdate _vfscommon) made children fail on
'invalid command name punkcheck:🔒:acquire' - the floor turns that
into a loud version-conflict in the child log.
src/tests/AGENTS.md records the floor rationale and the kit-hosted
child-suite requirement (vfscommonupdate-current kit content).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 week ago |
|
|
099ac699e3 |
G-097: bin utility naming sweep - punk-bits, punk-runtime, punk-tclargs, selfsign
The remaining pre-policy punkshell-own bin utilities take the punk- prefix (bin/AGENTS.md policy, G-096); external-tool wrappers (dtplite/sdx/kettle) and getpunk stay unprefixed. No behaviour changes ride along. - runtime scriptset: sources/toml renamed (src/scriptapps/bin/punk-runtime.*), the eight ps1 usage/guidance messages now say punk-runtime.cmd, the bash payload's filename-derivation comment example updated; REWRAPPED -> bin/punk-runtime.cmd (checkfile clean) with the .ps1 twin regenerated as a byte-copy. The roundtrip + checkfile pins retarget the new names and pass. - tclargs + bits: sources/tomls renamed; bin artifacts moved BYTE-FAITHFULLY (git mv, no rewrap): a pre-rename drift check showed both carry pre-template-refresh wraps (477-byte delta = the template's 2025 wmic-deprecation timestamp fix; runtime was in sync). Regenerating them is a behaviour change and is deliberately not smuggled into the rename - recorded in the goal. Fresh .ps1 twins cut from the current .cmds; stale untracked bits.bat/bits.ps1/tclargs.ps1/runtime.ps1 removed. - selfsign experiments: SELFSIGN.PS1 -> punk-selfsign.ps1 (case normalized), wrap toml + cert-create script renamed; the four untracked bin experiment scripts renamed on disk; the exported .cer is not a script and keeps its name. - runtimebash_wsl.test: functional staged-filename sites updated (bash ./punk-runtime.bash; solo-fixture cp) along with comments. - Docs: bin/AGENTS.md (examples, policy paragraph records the sweep, runtime contract section, pin pointer corrected to runtimecmd_roundtrip.test), src/scriptapps/AGENTS.md, root AGENTS.md, README.md, src/README.md, untracked bin/runtime/README.md, G-060 reference, libunknown comment (src copy; root modules/ + bootsupport copies catch up on their re-vendor cycles). Suites green: scriptwrap + binscripts 26 run / 25 passed / 1 constraint-skip / 0 failed - the roundtrip pin passes against the renamed artifact. Discovered and recorded for user decision (goal Progress): the project LAYOUT stores ship stale utility copies - runtime.cmd (2025-era payload) and getzig.cmd (the G-096 rename missed this channel) - so generated projects still receive old-named utilities; folding the layout channel into this goal's scope vs a layout-sync mechanism is flagged. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
c9c8a932e7 |
concurrency.test: retrying workspace cleanup for background-child log race
The two child-spawning tests (two-writers, lock-holder) proceed on the children's done-marker files, but a just-finished child can still hold its redirected stdout log open for a beat after writing the marker - on Windows the -cleanup tree delete then hits 'permission denied' (observed as a ~1-in-3 flake under the slower Tcl 8.6 interp, exposed by the new native-8.6 runtests support; same race existed under Tcl 9). cleanup_workspace retries the delete briefly (10s deadline) instead of flaking. 8/8 consecutive clean runs under 8.6.17 post-fix; Tcl 9.0.3 punkcheck subtree 84/84. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
1fbee821fc |
runtests: native Tcl 8.6 support via guarded punk::lib compat load (lpop)
The validated compat family is brought across for the harness: guarded 'package require punk::lib' when ::lpop is absent, at both boot levels - the toplevel two-stage boot (right after punk::args, whose parse needs lpop at runtests.tcl's own argument parsing) and the singleproc testinterp (before the shellrun preload, whose runx parses via punk::args::parse). No-ops on Tcl 8.7+/9: -discover-only stays ~0.35s. Native 8.6.17 verification: -discover-only works; punkcheck subtree 84/84, punk/lib subtree 43/43+1 gated skip, runner discovery suite 22/22, and a multiproc (-singleproc 0) probe 49/49. Tcl 9.0.3 regression per the src/tests/AGENTS.md runner-change contract: full suite in both modes with -report json, runtests_parity.tcl reports PARITY: ok (files=96 total=1064 passed=1047 skipped=16 failed=1 - the sole failure is the documented pre-existing exec-14.3 baseline). src/tests/AGENTS.md records the supported-interpreter change and the still-broken punk86-kit runtests route (kit/dev module skew - use a native 8.6 tclsh for 8.6 legs). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
a55344faa1 |
punk::lib 0.5.1: compat::lpop builtin-parity fixes, validated by differential matrix
Reviewed against the real 8.7/9 lpop via a 24-case differential (results,
final list state, error messages, errorcodes) - the compat proc was
correct on every success path; all divergences were error-path:
- out-of-range errors said 'tcl_lpop index ...' with no errorcode; now
the builtin's exact message and {TCL VALUE INDEX OUTOFRANGE}
- variable-access failures named the internal upvar link variable and
flattened detail (missing array element misreported as 'no such
variable'; unset var lost its TCL LOOKUP errorcode). Fixed by probing
with a plain read in the caller's frame BEFORE creating the upvar
link - through a link, or once a link merely exists, Tcl downgrades
the error class.
Finding: the assumed 8.6 divergence does not exist - 8.6's core index
parser already accepts TIP-176 M+N arithmetic, so compat::lpop now has
zero known divergence from the builtin (doctools note corrected).
compat.test extended (3 -> 10 tests): a differential parity matrix that
runs wherever the builtin exists (self-updating pin against future core
changes), static pins for values/errors/errorcodes that also run under
8.6 where no builtin exists, an unconditional M+N arithmetic pin, and
an 8.6-only pin that punk::lib installs lpop as the compat alias.
Green under Tcl 9.0.3 (9 pass/1 gated skip) and native 8.6.17
(9 pass/1 gated skip).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 week ago |
|
|
269b1af82b |
G-095: punkcheck 0.6.0 concurrent-writer safety - atomic saves, advisory event-scoped locking
Saves are write-temp-then-atomic-rename with bounded retry for Windows
sharing violations; load_records_from_file retries transient open
denials during a writer's replace window (parse errors stay strict -
they mean real corruption). Readers gain torn-read immunity with no
reader-side protocol.
New punkcheck::lock namespace (PUNKARGS-documented): advisory sibling
lockfile <punkcheckfile>.lock via open {WRONLY CREAT EXCL}, contents
naming holder pid/host/installer/timestamp, channel held open for the
duration, in-process reference-counted re-acquisition (sequential
make.tcl installers over one root must not self-deadlock). start_event
acquires; event end / installtrack destroy releases; flushes and
chokepoint saves outside an event take a transient lock. Contention
retries with backoff to -timeout (env PUNKCHECK_LOCK_TIMEOUT, default
15s) then errors naming the holder; stale locks break on provably-dead
holder pid (twapi process_exists / kill -0, capability-gated) or age
(-staleage / PUNKCHECK_LOCK_STALEAGE, default 300s).
Deferred flushes merge own records (INSTALLER by -name, touched
FILEINFO by -targets) into freshly-loaded file state under the lock
instead of wholesale overwrite; an mtime/size tripwire warns when a
non-protocol writer (e.g. older vendored punkcheck) touched the file
between load and save.
Duplicate-INSTALLER recovery: clean actionable error when stdin is
non-interactive (punkcheck::lib::stdin_is_interactive - strict twapi
GetConsoleMode on the real stdin handle on Windows, -inputmode probe /
test -t 0 on unix); the interactive prompt gains the synced-targets
deletion-wedge caveat. default_excludefiletail_core adds .punkcheck.*
so protocol siblings are never installable content.
Consumers verified without edits: cli and five make.tcl sites end their
events (lock released at end); make.tcl's vfs/bin kit flows destroy
their installers on every path (destructor releases).
New concurrency.test (6 tests): two child installer processes with a
polling reader (no parse errors, both installers survive, no duplicate
INSTALLERs, no lock/tmp leftovers), lock timeout naming the holder then
success after release, dead-pid and age stale-breaks against planted
lockfiles, non-interactive duplicate-INSTALLER error via pipe-stdin
child, protocol-sibling exclusion pin.
Matrix: Windows Tcl 9.0.3 84/84 (runtests), Windows Tcl 8.6.17 84/84
(direct tcltest drive - the runtests harness itself needs lpop under
native 8.6), linux WSL tclsh 8.6.14 84/84 (native-FS staged run).
punk/mix subtree unaffected (150 pass / 1 known constraint-skip).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 week ago |
|
|
b838a53921 |
G-094: punkcheck 0.5.0 single record lifecycle - OO installtrack sole implementation, per-event persistence policy
installtrack/installevent is now the only implementation of the .punkcheck record lifecycle (targetset init/add-source/started/end). Each event takes a persistence policy at start_event (-persistence eager|deferred): eager keeps the current per-op read-modify-write behaviour; deferred accumulates updates in the installtrack's in-memory working recordset until an explicit $installer flush (event-scoped save). QUERY stays never-persisted. punkcheck::install rebuilt as a tree-walking OO consumer in deferred mode - its records now carry the full field set (-metadata_us/-ts_start_transfer/ -transfer_us/-cksum_us and -targets_cksums incl all-targets mode), pinned field-equivalent with OO-installed records by the new lifecycle.test. Legacy zero-caller proc pipeline (start_installer_event, installfile_begin/ started_install/finished_install/skipped_install) retired to error-with- pointer shims; installfile_help rewritten for the OO lifecycle; the live shared engine installfile_add_source_and_fetch_metadata is unchanged. punk::mix::cli's commented-out legacy call sites removed (0.5.1, no behaviour change). Single save chokepoint: every lifecycle write funnels through installtrack save_working_recordset - the G-095 attachment point. Coherence and latent fixes (each pinned in lifecycle.test): - start_event refreshes the working recordset; sequential events on one instance no longer clobber prior targetset writes (end/end_event now clears the active-event slot, so a second start_event is valid) - event reconstruction maps record -ts_begin/-ts_end to constructor opts (flush no longer rewrites prior event history timestamps) - installtrack as_record: stray backslash-space wrote -name with a trailing space, breaking by-name lookup after any flush - get_recordlist misspelled variable; targetset_dict nonexistent helper - extract_or_create_fileset_record stdout print removed (isnew returned; targetset_init reports via debugchannel); dead targetset class removed Pin flip (recorded in installtrack.test): the full-lifecycle test's end + end_event double-end now correctly errors - lifecycle uses one of $event end / $installer end_event, matching all real consumers. Suites: punkcheck install/installtrack/lifecycle 78/78, punk/mix subtree incl cli prune.test 144 pass / 1 constraint-skip on native Tcl 9.0.3. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
8dde10bbdf |
runtests: punk-kit hosts launch children in 'src' package_mode; tally shows Testfiles-failed
Under punk91/punk902z/punk905_beta, '-include-paths modules/punk/console/*** -jobs 16' failed all 7 files with zero tests run: child processes boot via plain kit script dispatch, preloading kit-stamped punk packages (punk::console 0.7.2) before the payload's src paths apply - the suites' pinned 'require punk::console 999999.0a1.0-' then version-conflicts and the child exits 1 (the known shadowing runtests already warned about). Fix: when the host is a PUNK kit (kit container heuristics AND the ::punkboot namespace marker from punk_main.tcl boot) children launch as 'kitexe src child_test_runner.tcl ...' so they boot the project's src dev modules - matching what the payload selects. Non-punk kit containers (e.g tclsh90szip.exe: zipfs app mount, no punk boot) keep the old warning and get no extra arg. runtests_run_child_process gains a required exemodeargs param (tpool info args/body replication unaffected). Tally: file-level failures are not test results, so a FAIL run could sit beside 'Failed 0' unexplained (user report). The tally line now appends a fail-coloured 'Testfiles-failed N' whenever testfiles failed. Verification: console suites 71/71 under punk905_beta, punk91, punk902z (previously 0 run / 7 files failed); native Tcl903 + suite tclsh90s unchanged 71/71 with no modeargs; tclsh90szip warning path passes; tally demo shows 'Total 0 ... Failed 0 Testfiles-failed 1'. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
d3cc914a52 |
punk::libunknown epoch-copy unsoundness fix - tkconsole repl failure root-caused (G-098)
Copying ::punk::libunknown::epoch verbatim into a fresh interp/thread carries per-epoch 'added' maps that drive zipfs_tclPkgUnknown's can_skip_sourcing short-circuit - sound only in the interp that performed the scans. Packages the donor obtained at an earlier epoch (or with no unknown call: Thread is baked into thread::create'd threads) are absent from the donor's current-epoch map, so recipients skip their pkgIndex sourcing and requires fail where stock tclPkgUnknown would succeed. Bit deterministically as repl_console_backend_tkconsole under the suite 9.0.5 runtime: 'package require Tk' bumps the epoch pre-init, the codethread inherits the post-bump sparse map, the code interp then can't find vfs/Thread/registry, its init aborts before the G-001 conredirect junction vars exist, and the first pending-collect error left the repl reader inactive until the driver failsafe. Tcl903 escaped only by an accidental extra epoch bump in its code interp (fresh map, full rescan). Fix: punk::lib::libunknown_epoch_export (PUNKARGS-documented) - epoch record with every 'added' map emptied; counters/untracked/scripts/index globs preserved. Used at all four propagation sites (interp_sync, snapshot, repl %lib_epoch%, repl safe-arm). Hardening: the repl pending-collect now tolerates missing junction vars so a code-interp init failure can't wedge the reader. Also: test socketpairs pinned to -myaddr 127.0.0.1 (all-interfaces listens raised windows firewall consent popups for each newly built test exe - user datapoint). Verification: consolebackends 3/3 both runtimes (suite 42s->14s); full runtests sweeps identical on suite runtime and Tcl903: 1037/1021/15/1 with the sole failure exec-14.3 (documented machine baseline). G-098 acceptance sweep met. Pre-existing PUNK_TEST_TK opt-in quirk noted in the goal (silent early end, both runtimes, out of scope). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 week ago |
|
|
bc958300b1 |
G-093 rework: punk::path *** pathglob + separable lattice; runtests passthrough targeting
User-approved contract amendment replacing the day-1 file-relpath filter: one
directory-oriented pathglob semantics at every layer, with the ergonomics gap
closed in the syntax itself.
punk::path 0.4.0:
- *** as a whole segment matches ZERO or more segments (join-aware regex in
pathglob_as_re: an adjacent separator is absorbed into an optional group),
so X/*** = X and everything below - the subtree spelling; ***/f.txt matches
at any depth including the root.
- include separability fix: an exact or single-segment-glob full match no
longer sets allbelow (the deep walk previously dragged the whole subtree in
for X and X/* patterns; the zipfs walk was already separable).
- exclude separability fix (new exclude_state classifier, both walks): only
**|***-tail patterns prune the matched subtree; other matches exclude just
that directory's files - the **/_aside vs **/_aside/** argdoc distinction is
now real. Dead _path_matches_any removed.
- legacy bare-* include collapse removed (a * in -include-paths is the
one-below lattice form, not a match-everything alias; no caller used it).
- globmatchpath default-nocase driveletter exception rewritten as a direct
regex-head rewrite (the regex-text file-split broke on c:/***'s glued group
and accepted non-alpha drives).
- path.test +5 lattice/*** pins (40 total).
runtests.tcl:
- -include-paths/-exclude-paths pass through to treefilenames unchanged;
argdocs teach the separable X | X/* | X/** | X/*** lattice; directory and
file-name axes independent (tails); single-file targeting = exact dir
pattern + file tail.
- -serial-paths reconciled to the same directory-of-file reading (default now
modules/punk/console/*** modules/opunk/console/*** via
runtests_discovery::dir_matches_any) - the pre-existing file-path serial
matching was the other same-option-different-referent divergence.
- per-pattern zero-match stderr advisory (the X/**-for-subtree foot-gun points
at X/***).
- json report emitter: whitespace-padded entier-looking values now take the
quoted-escaped path ('string is entier -strict' accepts surrounding
whitespace - a failed test's "0\n" result_was embedded a raw newline and
truncated the parseable report line).
- testsupport/discovery.tcl now a thin passthrough (requires punk::path
0.4.0-); pathdiscovery.test rewritten to the directory-semantics contract
(22 tests incl. the X/** zero-match advisory characterization); AGENTS.md
targeting guidance swept to /*** across src/tests and src/modules/opunk.
Verification (native tclsh 9.0.3, piped, serialized): 45-probe matrix, path
suite 40/40, runner suite 22/22; vs the pre-G-093 baseline the default
discovery FILE SET differs by exactly the added runner suite and result
parity only by the five new path tests (+ that suite); mode parity -jobs 16
vs singleproc: PARITY ok (94/1037/failed=1 exec-14.3). Goal contract amended
in the detail file; full record there.
Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
e5060160b4 |
G-093: runtests file-relpath path targeting - include fix, -exclude-paths, -discover-only
Root cause (recorded in the goal file): punk::path::treefilenames matches -include-paths against the DIRECTORY containing files, and its documented X/** boundary semantics exclude files directly in X - so suites keeping .test files at the subtree root (scriptwrap, binscripts, punkexe) were silently missed by X/** targeting: the G-092 four-pattern (2/13 files) and repeated-flag (zero files) failures. punk::args -multiple accumulation probed healthy - repeated flags and a single space-separated value reach discovery identically; no punk change was needed or made. runtests.tcl now filters the tailbase-relative FILE paths after an unrestricted walk (new testsupport/discovery.tcl: globmatchpath, any-include-match, exclusion wins): X/** includes files directly in X, an exact relative path targets a single file, a bare directory path matches nothing (append /**). -exclude-paths exposed (same syntax and accumulation, exclusion wins over inclusion). -discover-only prints the discovered list plus a RUNTESTS_FILES tcl-list line and exits before any run machinery - subsecond via a two-stage boot (discovery phase loads only punk::args + punk::path; punk/Thread/shellrun/punk::tcltestrun and the testinterp/child path assembly load after the exit). New regression suite runner/testsuites/discovery/pathdiscovery.test (23 tests: pure filter, fixture-tree walk+filter, end-to-end -discover-only children including both G-092 characterization forms; ~7s wall, parallel-safe). src/tests/AGENTS.md targeting wording reconciled; new src/tests/runner/AGENTS.md. G-093 index status proposed -> active (user-directed). Verification (native tclsh 9.0.3, piped Bash context): pre-change baseline default -jobs 16 (93 files / 1010 tests / failed=1 exec-14.3 only) vs post-change -jobs 16 with -exclude-paths runner/**: PARITY ok; post-change default run differs from baseline only by the added suite (+23 passing); mode parity -jobs 16 vs singleproc sequential: PARITY ok (94/1033/1). Claude-Session: https://claude.ai/code/session_01BNUVVkYq9vHa6G3S9a3XTZ Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
e2fc7332fe |
G-087 stages 4+5: overlay merge primitive, marker/matrix retirement, version seeding
Stage 4 - documented overlay semantics implemented (commandset::layout 0.2.0): layout_materialize resolves a layout to its overlay chain (vendor tier then custom tier per store+vendor, <name>@<base> derived-layout folders expanding their base chain first, cycle-guarded) and composes multi-folder chains into a disposable staging dir applying <item>.anti deletion markers (zero-byte marker files recommended - committable, unlike the originally documented empty marker folders, which are also accepted). Single-folder chains with no markers are used in place, so punk.project (store and zipfs modpod) behaviour is unchanged. project.new (commandset::project 0.4.0) copies from the materialized path and the layout listing/scanning commands show the effective merged view. Fixtures: punk.othersample is now a live derived layout (new custom-deck fauxlink ref + .gitignore.anti demo marker); extra.txt/store README rewritten to the implemented semantics. New tcltest suite src/tests/modules/punk/mix/testsuites/layout/materialize.test (20 tests). Anti markers deliberately stay a plain filename convention rather than tag-bearing fauxlinks: a fauxlink is a reference tooling may follow (fcat auto-follows), a marker is a tombstone with no target. Stage 5 - retirements and generated-project version seeding: - The empty unimplemented child-side src/PROJECT_LAYOUTS_CREATE_FROM_... marker folder is deleted along with its project.new and make.tcl sync exclusions. - The vendor/custom x _project matrix collapses for layouts: custom/<vendor> is the one override level; _project folders join no overlay chain (the pseudo-vendor remains for decktemplates module/utility templates only). - project.new seeds generated projects post-materialization (only-if-missing, never from payload): punkproject.toml ([project] name + 0.1.0), a matching CHANGELOG.md ## [0.1.0] header, and punkorigin.toml - an interim generation provenance baseline (utc, layout name + resolved store target, punk::mix::templates version, punkshell version when derivable, origin path) for the G-027 pull design to adopt (noted in G-027). Also: script-mode/programmatic project.new robustness (explicit shellrun require; punk::mix::util askuser/do_in_path/foreach-file fully qualified - the util:: shorthand exists only after cli commandset import). Includes the concurrently-landed (other session, previously uncommitted) 0.3.1 early module-name validation fix in project.new, shipped within the 0.4.0 bump. G-087 flipped achieved 2026-07-19 (verification in the detail file; archive move follows in the next commit). punkshell 0.16.0 -> 0.17.0. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
4fc1d62ce2 |
agent skills: tcl-nslist namespace discovery; punk::ns 0.9.1 packagetails fix
New scriptlib/developer/nslist.tcl backing the new cross-framework tcl-nslist agent skill (.agents/skills/ canonical, .claude/skills/ synced copy): the discovery counterpart of whatis.tcl - lists what a namespace/package actually exposes at runtime via punk::ns::get_ns_dicts (the n// machinery): child namespaces with loadable-package markers, commands classified by kind, punk::args-documented commands, -synopsis whole-namespace usage lines, -pathcommands namespace-path resolution. Auto-package-requires unloaded packages and follows ensemble commands to their implementation namespace. The tcl-whatis skill/script cross-reference it (whatis redirects with a hint when the queried name is a namespace, not a command). punk::ns 0.9.1: get_ns_dicts packagetails/packageprefixes initialization moved inside the per-namespace loop - with multiple matched namespaces (path globs, trailing **) every dict after the first carried the union of all earlier namespaces' entries, mis-marking non-package children in nslist/n// underline styling and in the returned data; a child with several deeper packages below it was appended to packageprefixes once per matching package (now once). Pinned in nslist.test (nslist_classification_multins_package_buckets_reset). Documentation-only PUNKARGS added for get_ns_dicts (returned dict keys documented) and nslist_dict; parsing stays manual. Root AGENTS.md: introspection note + scriptlib/developer inventory updated. Project version 0.15.1 + CHANGELOG entry. punk::ns suite 102/102 pass. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
7e9eced51e |
lean test children: explicit suite deps, shellrun preload removed (-jobs ~50s)
The multiproc child bootstrap no longer preloads shellrun + the no-op runx warmup: 17 test files gained their missing explicit package require lines (punk::ansi for the bare ansi suites, punk::args for the bare args suites incl dev/dynamic-cache, punk::lib for the lib suites and for grepstr/untabify/examples whose punk::ansi/punk::args commands reach punk::lib internally, plus textblock for examples.test - caught by the empirical lean run: punk::args only soft-requires textblock and punk::args::helpers::example calls textblock::join). Children now load only tcltest plus each file's declared deps; the singleproc testinterp keeps shellrun as the runner's own capture mechanism. Module-web finding recorded in src/tests/AGENTS.md and the test-file comments rather than fixed: punk::ansi and punk::args call punk::lib without requiring it, and a hard back-require is blocked by punk::lib's own hard require of punk::args (cycle) - deps declared at test level; a considered module-level resolution remains open. UDP watch-mode note folded into child_test_runner.tcl per user direction: no interaction today (the parent relays child output at file granularity; verified post-lean - events + relay flow); any future live per-child tee must be conditional on PUNK_TEST_UDPTEE so unwatched children stay lean. Verified (native tclsh 9.0.3): full-suite PARITY ok for lean -jobs 16 vs the pre-lean baseline, between repeated lean -jobs 16 runs, and lean -jobs 1 vs -jobs 16 (989/973/15/1, exec-14.3 sole failure). Timings: -jobs 16 70.7s -> 49-53s; sequential multiproc ~5m30 -> 4m32; singleproc unchanged. AGENTS scaling guidance refreshed. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
276eff850d |
runtests: ANSI red/green/yellow status indicators for human output
User request after console-context failures went unnoticed: compact per-file status words, failure/warning list entries, the per-file had-failures/passed/child-failed notices, the markdown failures/warnings file lists, the tally Passed/Failed segments and a coloured overall STATUS on the DONE line are now SGR-coloured (green pass, bold red fail/error, bold yellow warning). Gating: -colour auto|on|off (default auto) colours only when stdout is a real windows console, detected via twapi GetConsoleMode on the STD_OUTPUT handle - the isatty-equivalent; get_console_handle proved unsuitable (it succeeds for piped children of console shells, verified both ways). NO_COLOR honoured in auto. Machine output (RUNTESTS_RESULT, json) is never coloured; piped output stays plain for agents (verified zero escape bytes piped, codes present with -colour on). Raw literal SGR is used rather than a+/a so the runner's indicators are independent of punk::console's process-global colour state (the same 2026-07-19 console runs showed that state shifting under mixed tty-ness). The previously UNCONDITIONAL raw-red errorInfo block in the file-error branch now goes through the same gate, so piped error output is cleaner than before. Also sharpens the -jobs guidance wording: subtree runs (e.g 28-file modules/punk/args/**: ~50s sequential vs ~11s at -jobs 16) benefit from -jobs - only single-file/few-file runs do not. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
913ea749a1 |
tests: decode console utf-16le stderr in capture_stderr helpers
dynamic_bad_tag_warns_once failed (count 0) ONLY in console-attached singleproc runs (user report; reproduced deterministically with stderr on a real console and stdout redirected): when stderr is backed by a windows console channel, a pushed chan transform receives the console driver's utf-16le wide-char byte stream - every ascii char arrives NUL-interleaved, so content regexps never match. The punk::args warning itself emits correctly, exactly once, inside the capture window (proven with marker writes: markers and warning all captured, all wide). Piped/file stderr and -jobs child processes deliver plain bytes, which is why every piped run passed. Fix in all three capture_stderr helpers (punk/args dynamic.test, punk/ansi grepstr.test, punk/ns corp.test - identical latent defect): if the captured data is NUL-interleaved, decode it as utf-16le (fallback 'unicode' for tcl 8.6) before returning. Verified: the console-attached args subtree run is green (246/243/3/0); piped runs unchanged. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
a590ff4aec |
src/tests/AGENTS.md: -jobs guidance updated with measured scaling curve
User-measured reference-machine numbers 2026-07-19: -jobs 8 ~79-86s, -jobs 16 ~61s (~5.6x vs ~5m40s sequential), plateau by -jobs 24 (~60s). Guidance now recommends -jobs 16 and records the plateau anatomy (slowest single child ~31s runtimecmd pair, serial console tail ~16s piped / larger under a real console, ~10s runner overhead). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
57b3b86e0a |
runtests: report total elapsed seconds in all report styles
The '### runtests DONE at <ts>' human line gains '(elapsed <N>s)', the RUNTESTS_RESULT summary line gains a trailing elapsed_seconds=<N> key=value, and the json report gains a top-level "elapsed_seconds" field - matching the name already used by the watch-mode run-end event, which now shares the same computed value. Additive only; the parity tool reads named keys and is unaffected (verified on all three report styles). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
5002371864 |
Split long-running test files to lower the -jobs parallel floor (G-092 achieved)
multishell.test (10 tests, ~105s solo child - the -jobs floor) split five ways along shared-fixture boundaries, every test moved verbatim with its provenance lines: multishell.test keeps wrap + structure/LF-only + exec smoke (incl WSL); multishell_wrapverify.test (fresh-wrap checkfile) and multishell_wrapdeterminism.test (byte-identical re-wrap) each re-pay the wrap fixture; runtimecmd_checkfile.test and runtimecmd_roundtrip.test guard the committed bin/runtime.cmd and its source round-trip with no wrap fixture at all. argparsingtest.test (17 tests, ~32s) split into timeit/discover/contract/first_call (11) + argparsingtest_compare.test (compare_*, 6). Assessed and left unsplit: dtplite.test (24.6s solo), scriptexec.test (12s); exec.test excluded as imported core material. File headers point at the src/tests/modules/AGENTS.md punk/mix bullet for the sibling map; the runtests longest-first weight table carries measured post-split weights. runtests_parity.tcl gains a -names mode: multiset comparison of '- testname:' lines from '-report markdown -show-passes 1' captures, file attribution ignored - verbatim moves compare identical, lost/ duplicated/renamed tests are reported. Verified (native tclsh 9.0.3): repeated -jobs 8 full-suite runs 1m26.3s / 1m26.8s (was 2m16s at G-091, ~5m40s sequential - 4.07x vs the pre-parallel baseline, 36.6% vs the G-091 reference); slowest child 30.7s / 31.3s (bound 45s); NAMES identical (989 occurrences) vs the pre-split sequential capture; tallies identical in every run (989/973/ 15/1, exec-14.3 sole failure, files 87 -> 92); PARITY ok -jobs 8 vs -jobs 1 and between repeats; repo clean after runs. Notable finding recorded in the goal file: child-wall contention inflation (~45% with 50s+ dominant children present) collapsed to ~15% once the work distribution was flattened - splitting reduced both the critical path and the contention itself. G-092 flipped to achieved 2026-07-19 and archived (GOALS-archive.md record, detail file with full verification evidence to goals/archive/). goals_lint clean. Also noted in the goal file, out of scope: runtests -include-paths multi-pattern/repeated-flag matching misbehaved during measurement (single value with four deep patterns matched one; repeated flags matched zero) - contradicts documented semantics, needs its own investigation. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
1a1847c2e7 |
runtests -jobs N parallel test execution (G-091 achieved)
-jobs N (implies -singleproc 0; explicit -singleproc 1 conflicts) runs test files through a tpool of N concurrent child processes with per-child capture files and tcltest -tmpdir subdirs, longest-first static-weight submission, and a -serial-paths serial tail (default: the console-state suites modules/punk/console/** + modules/opunk/console/**; piped-child-driven suites proved parallel-safe and each serial file costs its full child boot strictly after the parallel phase). Cached results feed the unchanged processing loop in discovery order, so reports are identical in shape and order to sequential runs. Watch mode emits file-collected events (completion order, output relayed there); file-end (tallies) stays discovery-order. The runner now reports jobs phase times and the ten slowest child WALL times (child wall includes boot + file-level fixture cost that per-test usec misses). Two Tcl-core-level behaviours found and worked around in the child spawn (see the verification record in the archived goal file): - concurrent BLOCKING execs from worker threads convoy on Windows (all return at the longest concurrent child's exit; plain sleepers 2-12s from 8 workers all walled at 12.0s) -> spawn via 'exec ... &' and poll per-pid tcl::process status; blocking fallback retained for runtimes without tcl::process (tcl 8.6). - Tcl_ReapDetachedProcs runs on every exec and purges finished background children process-wide, racing the poll (nondeterministic 'key <pid> not known in dictionary') -> tcl::process autopurge false + explicit per-pid purge after the status read. Verified on native tclsh 9.0.3: repeated -jobs 8 full-suite runs 2m16.2s / 2m15.6s with PARITY ok vs -jobs 1, between repeats, and vs the pre-parallel baseline (987-test identity, exec-14.3 sole expected failure); 2.58x vs the ~350s sequential baseline (2.41x vs one cooler-machine 5m28.8s sequential run - recorded in the goal file); repo clean after every run. G-091 flipped to achieved 2026-07-19 and archived (entry to GOALS-archive.md, detail file to goals/archive/ with the verification record; reference sweep updated runtests.tcl comments and the src/tests/AGENTS.md marker). goals_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
a65f9e5b67 |
shellrun 0.2.0 runx -teelog + runtests UDP watch mode (PUNK_TEST_UDPTEE)
runx -teelog {-tag/-syslog/-file/-raw settings}: live tee of the
captured stdout/stderr to shellfilter::log workers (log sources
<tag>stdout/<tag>stderr) while captured/returned data is unchanged.
Implemented as write traces on the capture variables rather than extra
channel transforms: probing showed a tee_to_log float combined with the
float-locked capture junction is starved or loses its worker settings
through add/remove churn (float-placement logic is unaudited - README
'very unripe parts'), and shellthread's parked-worker adoption does not
re-apply settings (writes silently misroute to a previous target). Both
findings deliberately not addressed here - recorded for a proposed
shellfilter/shellthread audit goal. Tag workers stay open for reuse;
conflicting reconfiguration errors explicitly.
runtests.tcl watch mode: env PUNK_TEST_UDPTEE=<port>|<host>:<port>
streams runner lifecycle events (tag 'runtests', tcl-list
RUNTESTS-EVENT messages: run-start/file-start/file-end/run-end with
tallies) and test output (tags teststdout/teststderr) to a local UDP
listener via the same mechanism - live per chunk in singleproc mode
(runx -teelog inside the testinterp), relayed per completed file by the
parent in multiproc mode. Watch mode terminates the per-testinterp log
worker threads after each file; unwatched runs are unchanged (including
the pre-existing teehandle-worker leak, also noted for the audit). The
parent extends auto_path with <projectroot>/lib_tcl<N>/<arch> so
workers load tcludp 1.0.13+ (1.0.12 UDP_ExitProc = G-036 exit-hang
class).
Verified on native tclsh 9.0.3: full-suite result parity (87 files, 989
tests, exec-14.3 sole failure) for watch-off and watch-on singleproc
runs vs the pre-change baseline; focused watch runs in both modes
captured over UDP (events + live/relayed output). Viewer-side caveat
documented: tcludp's receive fileevent under Tcl 9.0.3/Windows
delivered only the first datagram (send side unaffected; .NET UdpClient
received all).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
218fbb1c46 |
runtests.tcl: complete -singleproc 0 multi-process mode + parity harness
Multi-process mode previously execd bare test files with no environment (children died on their first package require) and misreported the crashes as missing-cleanupTests warnings with the stderr discarded. - testsupport/child_test_runner.tcl (new): per-file child bootstrap. Applies a runtests-generated environment payload (prefer latest, test tm paths, auto_path, modpod ifneeded defs, tcltest options; per-file -testdir computed child-side), warms 'clock format' before the module-path wipe (first script-level clock use loads msgcat from the runtime default paths, which the test paths do not supply), and mirrors the testinterp preload: package require shellrun plus one no-op runx -tcl call (runx execution pulls punk::lib; several suites depend on preloaded punk::* commands). - runtests.tcl: generate the payload per run; spawn children via plain exec with file-captured stdout/stderr and immediate-EOF stdin (mechanism reusable for future parallel -jobs scheduling); classify nonzero child exits as file-level failures with the stderr tail surfaced in all report styles (exit-0-no-summary remains the missing-cleanupTests warning); warn under kit executables (children boot with kit-stamped punk packages preloaded, shadowing src dev modules - prefer a native tclsh). - scriptlib/developer/runtests_parity.tcl (new): compares two '-report json' captures on result identity (per-file counts, failure/skip/warning identities; timings ignored), tolerating preamble noise and the ANSI SGR reset emitted on the JSON line. Verified on native tclsh 9.0.3: full suite singleproc vs multiproc PARITY ok (87 files, 989 tests, 973/15/1 with the documented exec-14.3 baseline as the sole failure); crash and warning classification exercised. Wall time ~5m50s in both modes. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
c05af65543 |
argparsingtest 1.0.0: per-style parser sets opts/tkstyle/tclstyle with N/A capability rows
Restructure of the parser-timing module around three calling styles:
- parser procs move into per-style child namespaces argparsingtest::opts /
::tkstyle (2 leading positionals) / ::tclstyle (2 trailing positionals),
with identical short proc names across styles; the test1_ prefix is gone
- hand-rolled parsers share a manual_ prefix (manual_ni, manual_switch,
manual_prefix, ...) so they group visually in the comparison tables;
test1_prefix2 removed (not meaningfully distinct from test1_prefix)
- tkstyle/tclstyle carry a representative roster (manual_switch baseline +
punkargs/punkargs_by_id/punkargs_parsecache + opt + cmdline + tepam);
style parsers return a {p1 p2 opts} list
- new 'unsupported' discovery status for library/style combos the backing
library cannot express: cmdline with leading positionals (getoptions stops
at the first non-option word - probe verified), argp with any positionals
(parseArgs walks the whole list as option pairs - source verified).
compare renders these as N/A rows below the timed rows so every library
still appears in every style's table
- harness procs (discover_parsers/timeit/first_call/compare) gain
-style all|opts|tkstyle|tclstyle and return results keyed by style;
-args requires a single -style (each style has its own default vector);
external probe keys drop the test1_ prefix (getopt/parse_args/argparse/cmdr)
- punkargs_by_id variants keep the eager punk::args::define as sole doc
source (the former duplicate argdoc lappend made the lazy namespace scan
undefine/re-register the id on first introspection); unused struct::set
require dropped; opt/cmdline/tepam requires hoisted to module top;
first_call library warm-ups extended with positional coverage
- test suite rewritten: 17 tests including per-parser {p1 p2 opts} contract
checks across both positional styles, N/A table rendering, roster counts
and the -style/-args error paths
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
1eb9dc690b |
punk::path 0.3.0: extensionless tcl scripts via lib: (first-line identification)
scriptlib_resolve now lets an extensionless (or unknown-extension) lib:<name>
call match a file named exactly <name> when its first lines identify it as
tcl: a leading '# tcl' comment (prefix, case-insensitive), a shebang naming
tclsh/tclkit/wish, or the portable sh-trampoline ('#!/bin/sh' with a
commented 'exec tclsh' continuation - detected within the first 4 lines).
New internal punk::path::system::scriptfile_is_tcl does the bounded sniff
(512 bytes, UTF-8 BOM and CRLF tolerated, directories/unreadable files
rejected). When both <name> and <name>.tcl exist, the spelling matching the
call wins, checked per scriptlib location so kit-internal directory
precedence is never crossed by a spelling preference.
.kit joins the known extensions: lib:<name>.kit previously had .tcl appended
(searched <name>.kit.tcl), which made the shell subcommand's do_tclkit
dispatch arms unreachable - lib: kit dispatch is now restored. Result dict
reworked: scripttype (tcl/kit/py/pl/ps1/sh or empty) + notes keys added,
scriptname is now the matched relative name, and matches require file isfile.
app-punkshell and app_shellrun lib: handling refactored onto the shared
resolver (previously independent inline copies of the policy), fixing two
silent-failure bugs in that copy: no message at all when a scriptlib dir
existed but lacked the script, and the error listing showing
<kit>/scriptlib rather than the <kit>/app/scriptlib actually checked.
app-punkscript's post-resolve gate now uses scripttype and its not-found
report includes the identification skip notes. The unused has_globchars
vestige is dropped.
Fixtures scriptlib/_punktest/{extless,dual,dual.tcl,shebang_sh,notatcl} and
5 new scriptexec.test cases (extensionless resolve, both precedence
directions, trampoline shebang + argv, non-tcl skip note on not-found);
suite passes 17/17 against a freshly built punk902z kit. Sniff helper unit
checks pass under tclsh 9.0.3 and 8.6. punkshell project 0.13.0 -> 0.14.0.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
75cffe21f3 |
punk::args 0.12.6 + punk::ns 0.9.0: LLM-oriented usage output; tcl-whatis agent skill
punk::ns 0.9.0: cmdhelp (i) gains -return text - plain-text argument
documentation for machine/LLM consumption: no ANSI, no table layout, the
argument section of every command form rendered in one output under a common
header ('i -return text after' shows all six forms), G-041 form selection
still honoured when argument words are supplied, no advisory-parse error
preamble (-return dict remains the parse-status surface). Implementation
delegates resolution to the -return dict recursion and renders per-form via
the string renderer.
punk::args 0.12.6 (user direction; string-form layout explicitly not frozen -
no external consumers yet):
- arg_error renders the error message + per-form match detail exactly once,
BELOW the usage display (was above and below); bottom append suppressed for
empty messages.
- string renderer argument rows are single-line
'name TYPE:type(constraints) ?DEFAULT:'val'? ?MULTI:yes?' - type
constraints parenthesize onto the base type instead of line-breaking
mid-row; empty DEFAULT/MULTI labels and whitespace-only help blocks omitted.
- choices render as markdown-subset bullets '- `choice` - label' with label
continuations at a fixed deeper indent - choice names are now
machine-distinguishable from label text without ANSI. Structural contract:
column-0 lines bearing TYPE: are argument rows, indented lines are
documentation, backticked bullets are choices. Table cells unchanged.
New scriptlib/developer/whatis.tcl (runtime command introspection for
agents): resolved name, subcommand-chain resolution via punk::ns::cmdinfo
('whatis string is'), kind, providing package + loaded version, origin file,
proc definition file:line, punk::args synopsis; -body appends the runtime
body with file-relative line numbers, -doc the full plain-text argdoc via
cmdhelp -return text (with fallback for older punk::ns). Backing the
cross-framework tcl-whatis agent skill: canonical .agents/skills/tcl-whatis/
(Agent Skills standard - pi/OpenCode/Codex) with byte-identical copy in
.claude/skills/ for Claude Code; .gitignore gains !.claude/skills/ with the
fossil ignore-glob comment + exception-set docs updated per the dual-VCS
contract (fossil adds staged). Root AGENTS.md: .agents/skills index entry,
whatis pointer in Repo-wide Notes, scriptlib/developer example.
Tests: new pins cmdhelp_return_text_all_forms/_argword_form_selection/
_single_form_plain_marker (cmdhelp.test), rendering_stringmode_singleline_argrows
+ rendering_stringmode_choice_bullets (rendering.test); deliberate-change pin
updates: errorselection.test message matches gained leading * and cmdhelp.test
message pins sample the last line (message placement). Full source-tree suite
963/979 pass, sole failure the pre-existing exec-14.3 baseline; make.tcl
modules clean.
Project version 0.12.42 -> 0.13.0 with CHANGELOG.md entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
c2574a7050 |
punk::args 0.12.5 + punk::ns 0.8.1: parse -cache overhaul, synopsis notation, eg resolution
parse -cache overhaul:
- VALIDATION trap's parse_cache write now explicitly gated on -cache (formerly
unconditional but landing in a discarded proc-local for -cache 0 by scoping
accident - 'variable parse_cache' only ran on the -cache 1 branch)
- cached validation errors stored as per {errorstyle callertext} render
variants under a {arglist definition form} main key (-caller dropped from the
main key - results don't depend on it); a missing variant falls through to a
fresh render. Previously the first caller's errorstyle and %caller%
attribution were baked in and replayed verbatim to later callers.
- @dynamic definitions (and legacy leading '-dynamic 1') are never cached so
re-evaluated substitutions always take effect; dev/dynamic-cache.test
known-bug pin flipped
- new punk::args::parse_cache view/clear proc (sgr_cache style); guarded
variable init; -errorstyle definition default corrected to the operative
'standard'. New parsecache.test (7 tests).
synopsis notation + internal @form -synopsis retirement:
- ::punk::args::parse/::parse_status dropped their stale @form -synopsis
overrides (omitted -cache/-caller) for auto-generated lines shaped with
-typesynopsis {<int|formname>...} on -form; drift pin
synopsis_parse_generated added
- punk::ns::synopsis no longer errors on custom @form -synopsis lines that are
not valid Tcl lists (e.g Tcl manpage style '?-form {int|<formname>...}?' -
's parse' raised 'list element in braces followed by ...'): non-list lines
take a textual command-head replacement fallback
- @form -synopsis directive help rewritten (display-only, any style, prefer
auto-generation, known warranted case: script-level/constructed ids);
::punk::args::synopsis -help gains a notation legend and a new @examples
block comparing Tcl man-page ?...? style with the bracket style (punk::args::eg)
eg usability + examples indication:
- punk::args::eg resolves relative/unqualified command names (punk::ns::cmdinfo
from calling context when loaded, else global qualification) - in namespaces
where it shadows the global 'eg' alias (e.g ::punk::args) 'eg list' returned
empty while 'i list' worked; unknown ids now return a message naming the id;
punk::ns::eg hands the typed name through on unresolved docids
- usage-table 'Example: eg <id>' header row now uses scheme colour CLR(check)
(interim display until G-088 footer/subtitle support)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
7a170a6a46 |
argparsingtest 0.2.0: parser timing comparison with cold+warm first-call metrics
New procs timeit/compare/discover_parsers/first_call for rough cross-parser
performance comparison (punk::args variants vs hand-rolled dict/switch/prefix,
tcllib opt/cmdline/tepam, argp), with PUNKARGS argdoc coverage throughout.
first_call times each parser twice in fresh child interps:
- cold: first call after package load (includes byte-compilation of the parser
proc body and any backing-library procs it invokes)
- warm: the backing library is pre-exercised via per-library sacrificial
warm-up scripts (library_warmups dict) so the timed call isolates per-proc
first-use cost. Replaces an earlier punk::args-only
'punk::args::parse {} withdef {}' warm hack that was unfair to the other
libraries under test and only partially warmed punk::args itself.
Child interps pin package requires to the parent's loaded versions
(punk::args, punk::lib when present, argparsingtest) - plain package require
prefers stable versions, so children otherwise timed older stable copies
visible on the module paths instead of the dev module under test; under
Tcl 8.6 the punk::lib pin also supplies the lpop compat shim punk::args::parse
needs, unbreaking punk::args timing in bare child interps there.
compare renders first_cold/first_warm columns (table), nested cold/warm
sub-dicts (dict/json). New test suite under src/tests/modules/argparsingtest.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
c55225a392 |
punk::args 0.12.4: collision-aware resolve miss path (undefined-id warning retired)
resolve's first-sighting path for a rawdef whose @id is already registered with different content now purges the id's existing cache entries (quiet undefine) before registering, mirroring define's re-creation behaviour. Previously it repointed id_cache_rawdef while stale rawdef_cache_about / rawdef_cache_argdata entries lingered - two rawdefs claimed the same id and a subsequent define with the original text was a silent no-op (stale cache-about hit), leaving withid lookups stuck on the inline definition. The disabled blanket "called with undefined id" stderr warning is removed - it flagged supported inline usage (parse ... withdef, direct resolve calls). Guard checks id_cache_rawdef directly (id_exists also matches aliases, where the rawdef lookup would error). Known residual: the miss path still records no -defspace for @dynamic definitions first seen via resolve. New define.test pin define_resolve_id_shadow (characterized pre-fix: the re-define no-op reproduced with the purge disabled). punk::args suite green under Tcl 9.0.3 (228 passed, 0 failed). punkshell 0.12.41. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
079caa9ae2 |
runtests.tcl: fix multiple trailing file tails collapsing into one glob
Two independent list-flattening bugs made `runtests.tcl foo.test bar.test`
match zero files, forcing agents to run files individually:
- the trailing glob value is -multiple 1, so its parsed value is a list;
plain lappend nested it as a single space-containing element
- punk::path::treefilenames declares tailglobs as a -multiple 1 positional
(one glob per argument), but the whole file_globs list was passed as one
argument, re-collapsing it (this also broke multiple globs supplied via
-tcltestoptions {-file {...}})
Single names always worked because a one-element Tcl list flattens to
itself, which masked both bugs. Verified: two file tails now discover and
run both suites (files=2, 40/40 pass).
Also note multi-file-tail support in src/tests/AGENTS.md Work Guidance.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
86883a496c |
punk::ns 0.7.1: hygiene-pass backlog fixes - nslist -types default, nsjoinall error prefix (pins flipped)
Both fixes were pinned as known warts before the change; the pins flip with it:
- get_nslist: the -types default sat inside a braced dict-create literal, so it
was the literal string $known_types - any call without -types (notably bare
user-level `nslist`) errored with the malformed "Unrecognised namespace
member type: $known_types". An unsupplied -types now defaults to all known
member types. Pin flipped: nslist.test nslist_types_default_error_QUIRK ->
nslist_types_default (bare nslist renders children + commands). nslist's own
PUNKARGS -types gained help text, deliberately without a -default so the
passthrough stays absent when unsupplied.
- nsjoinall: the non-empty-prefix-vs-absolute-path error message carried a
copy-paste "nsjoin:" prefix - now "nsjoinall:". Pin flipped in
nsprimitives.test nsjoinall_edges.
- nscommands: commented out a development trace puts (">>> base: ...") that
polluted stdout on the weird-namespace path (same treatment as the 0.1.1
doc-lookup trace-puts cleanup; not pinned).
Suites green: ns/nav/repl 111/111; full source-tree run at the known baseline
(only core exec-14.3, pre-existing). buildversion 0.7.0 -> 0.7.1; project
0.12.34 + CHANGELOG.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
13e38734b6 |
punk::ns 0.7.0: comment/doc hygiene pass - dead code removed, stale docs corrected, findings flagged
No change to shipped behaviour (ns+nav+repl suites 111/111 green). Minor bump
because unused procs were removed.
Removed (~1200 lines, recoverable via git history):
- the fully commented-out predecessor help command arginfo (~930 lines) -
its own header marked it replaced by cmdhelp
- superseded/deprecated name-primitive twins nsparts1, nsprefix1,
nsprefix_orig, nstail1, nstail_orig (never exported, no callers; NOT
drop-in equivalents - divergence on 5+ colon runs was pinned in
nsprimitives.test before removal; those divergence pins are removed with
the twins and replaced by a direct nsprefix long-colon-run pin - the
divergence record lives in the test file history, commit
|
2 weeks ago |
|
|
0c7168a178 |
ns tests: nsprimitives.test - name/path primitive + nseval-variant characterization (hygiene-pass pin gap closed)
20 pins for the previously near-unpinned punk::ns primitive region: nsparts/nsprefix/nstail/nsjoin/nsjoinall string behaviour incl weird colon-run (:::) splitting, trailing-colon parse ambiguity, round-trip exceptions; divergence pins proving nsparts1/nsprefix1/nsprefix_orig/ nstail1/nstail_orig are not drop-in twins (safe-deletion evidence); nseval create-on-eval + evaluator caching and the native-vs-punk p:::x resolution divergence; nseval_ifexists/nsexists/nschildren/nstree_raw on genuinely weird namespaces; globmatchns */**/? semantics (stale "should be fixed" comment above nsglob_as_re noted - behaviour fixed); nspath_to_absolute/nspath_here_absolute caller resolution. Warts recorded for the pass: nsjoinall error message says "nsjoin:". Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
2b46e2d86a |
shell tests: E3 piped-session proof of n/ namespace continuity and subshell carry-over (shellnavns.test)
New shell/testsuites/punkexe/shellnavns.test - one hang-proof punk_run piped session against the built executable in src launch mode (dev modules, so current punk::repl/nav source is exercised without a rebuild): PROVEN end-to-end: - n/ sets ::punk::nav::ns::ns_current in the running shell - the current namespace continues into `subshell punk` and back out, and the 0.5.2 stray-namespace seeding fix holds live (no phantom ns_current namespace in the subshell context) - navigation inside the subshell takes effect; the session exits cleanly (exitcode 0, no timeout, exit unwinds subshell -> parent -> terminate) FINDINGS from the E3 probes (pinned in the test with markers): - the FIRST subshell evaluates in the SAME code interp as the parent shell - the "first subshell asymmetry" already TODO-documented in repl::init. Continuity therefore manifests via shared state at shell level (SHARED marker: a variable set in the subshell is visible to the parent after exit, and the parent adopts the subshell''s final namespace). The repl::start seeding template - the carry-over mechanism for genuinely separate code interps - is proven at module level in punk/repl nscurrent.test. A G-002-style isolated subshell would flip these pins. - KNOWN GAP: piped-session submissions evaluate at :: even after n/ sets ns_current - the inscope application proven interactively and at module level does not take effect for subsequent piped submissions in this spawn shape. Root cause undetermined (piped-path evaluation vs kit/codethread interplay); flagged for investigation alongside G-038 session-context work. Verified: shell/** suite 42 total / 40 passed / 0 failed (2 gated skips) under Tcl 9.0.3. AGENTS updated (shell contracts bullet; punk/repl module index E3 reference). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
50e4c60649 |
n/ display+navigation characterization (nslist/navns/nscurrent tests); punk::repl 0.5.2 stray-namespace seeding fix
Groundwork requested for the future rework of n/ n// n/// output to punk tables with terminal-width responsiveness: the underlying display elements and navigation/retention semantics are now pinned so only deliberately REWORK-flagged pins flip when the layout changes. - punk/ns nslist.test (11): tier A pins get_ns_dicts classification buckets (the machine contract: children/packagetails/packageprefixes per the package-names derivation, commands/exported/imported/aliases/procs/ ensembles/oo/coroutines/usageinfo incl alias-target doc resolution and its update_definitions dependence, alias edge cases, native via builtin ns); tier B pins per-element marking layout-agnostically (underline/underdouble/ underdotted package styles, type tag colours, exported green / imported -I under overtype SGR canonicalization, the punkargs doc icon); tier C pins the CURRENT hardcoded 2-col/4-col layout and nspath subtables, explicitly flagged to flip with the rework; KNOWN QUIRK pinned: bare nslist without -types errors with a malformed message (literal dollar-known_types). Findings recorded: the red-strike/masked alias display branches appear unreachable from current bucket derivation. - punk/nav/ns navns.test (6, new suite dir): ns/ navigation state machine (absolute/relative/glob-no-nav/failed-nav preservation/quad-colon normalization), v-form content selection, ensemble annotation, and the ::punk::nav::ns::ns_current variable contract. - punk/repl nscurrent.test (4): repl retention proven against a REAL codethread (repl::init, synchronous runscript sends): inscope evaluation, retention across submissions, n/ navigation retained, auto-create-with- notice for a missing current namespace. - punk::repl 0.5.2 fix: repl::start''s codethread seeding template namespace-eval''d the full ns_current VARIABLE name, creating a stray namespace of that name in every code interp (phantom child in n/ listings of the nav namespace). Now ensures only the parent ::punk::nav::ns. Subshell namespace carry-over semantics unchanged; pinned behaviourally (mirrored template) plus a source-text guard, pending the planned end-to-end piped subshell test (E3) at the shell level. Verified: punk/ns 80/80, punk/nav 6/6, punk/repl 7/7 under Tcl 9.0.3; nslist/navns/nscurrent green under 8.7. Console queries mocked throughout (the render path consults get_size/get_tabstops). Project 0.12.33 + CHANGELOG; tests AGENTS.md index updated. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
e68cc1c223 |
punk::lib 0.5.0: has_tclbug_nestedswitch_tracelines check (behavioural probe of tktview 5d5b1052280c976ea3d4)
New check pair in punk::lib::check, in the established style (G-076
console_deadspin exemplar: pure facts-in/verdict-out classifier
tclbug_nestedswitch_tracelines_signature + has_tclbug_* proc returning the
standard buginfo dict {bug bugref description level}, auto-surfaced through
the help tcl warning report via the info procs enumeration).
Unlike the version-gated checks, this one is a LIVE behavioural probe (safe
and cheap - no console interaction): a dynamically-defined proc with a
nested 4-word switch is enterstep-traced for inner arm 1 (affected split-
list index 1 - reports line 3) and the default arm (index 5, beyond the
command word count - reports line 2 correctly), matched against the
characterized wrong/right signature. Detection therefore flips
automatically on a Tcl runtime containing the upstream fix - no fixed_in
version variable needed. Probe layout note: a 2-arm probe would put the
default body at affected index 3 and hide the signature (both arms
mismark) - the middle arm exists to push default to safe index 5 (this
initially bit the probe itself, confirming the law once more).
Followup-when-fixed documented in the proc: re-verify with
scriptlib/developer/tcl_switch_traceline_repro.tcl, flip the
ns/cmdtrace.test GAP pins and fixed-canary, update the punk::ns::cmdtrace
argdoc caveat, note the fixed-in version. New canary test
cmdtrace_upstream_bug_check_canary asserts the check still reports the bug
- on a fixed Tcl it fails first and points at that workflow.
Verified: punk/ns 69/69 and punk/lib 37/37 under Tcl 9.0.3; cmdtrace.test
6/6 under 8.7; all has_tclbug_*/has_libbug_* procs exercised help-tcl style
without error; probe self-cleans (no temp proc/var residue).
punk::lib buildversion 0.4.3 -> 0.5.0 (new API procs = minor); project
0.12.32 + CHANGELOG; tests AGENTS.md index updated.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 weeks ago |
|
|
cabde42e85 |
punk::ns 0.6.0: cmdtrace -pause flag; nested-switch traceline mismark characterized as upstream (tktview 5d5b1052280c976ea3d4)
cmdtrace gains -pause <bool> (default 1, existing interactive behaviour unchanged): -pause 0 bypasses the "paused - hit enter key to continue" askuser in _cmdtrace_leave so cmdtrace runs unattended and the marked-up traced-body report (return value) can be captured by scripts and tests. Line-mismark investigation (all punk-free raw enterstep probes, results byte-identical on Tcl 8.6.17 / 8.7a6 / 9.0.3 - conclusively upstream): - with the ::switch argdoc available (punk::args::moduledoc::tclcore), cmdtrace marks flat single-block switches and 2-word-form nested switches correctly for EVERY arm; the residual mismarks match the raw trace data - empirical law, predictive across 4 command shapes x 6 arms and deeper nestings: an arm body at index j of the split pattern/body list reports container-relative lines (shift = switch command line within its containing script - 1) exactly when j lands on a LITERAL word of the switch command (options, --, or the block); dynamic words and j beyond the command word count fall back to correct arm-relative attribution. Position-based, not call-order based. Explains the ticket observation that the affected-arm count "varies based on switch options". - suspected machinery: Tcl_SwitchObjCmd passes split-list index j as the TclNREvalObjEx word; TclInitCompileEnv adopts ctx line[word] when the index happens to be in range of a per-word array describing the switch command itself (the splitObjs munging looks intended to prevent this) Artifacts: - new tests ns/cmdtrace.test (5): -pause 0 smoke + error-call count, flat-switch and 2-word-nested correct-mark guards, upstream mismark GAP pins (gated on have_tclcoredocs - cmdtrace arm-offset correction parses supplied switch commands against the ::switch argdoc) - scriptlib/developer/tcl_switch_traceline_repro.tcl: standalone pure-Tcl repro + findings write-up, suitable as an attachment/addition to the upstream ticket - cmdtrace argdoc caveat updated: cites the ticket and the characterized pattern (was "possibly an unreported bug") Verified: punk/ns suite 68/68 under Tcl 9.0.3; cmdtrace.test 5/5 under 8.7. punk::ns buildversion 0.5.0 -> 0.6.0 (new flag = minor); project 0.12.31 + CHANGELOG; tests AGENTS.md index updated. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
765d24b302 |
tests: corp/grepstr/untabify characterization - punk::ns hygiene-pass precursor coverage
New punk/ansi suites and extended punk/ns corp.test, characterizing the corp -> grepstr -> untabify tab-handling interaction and the standalone behaviours. All console-query paths are mocked (the overtype renderline.test get_tabstops pattern, extended to get_size + punk::console::tabwidth): the -untabify none / -stops terminal / -stops <int> paths consult punk::console::get_tabstops / get_size which emit live terminal queries that block or error in headless/piped environments - mocking is the answer to probing that behaviour deterministically in the test harness. - ansi/untabify.test (10): -stops 8/int/list/terminal(mocked), -with spaces/unicode(U+21E5 + U+00A0)/custom pair, multiline, usage errors, and the EXPERIMENTAL -plastic elastic-tabstop mode: basic expansion, the cross-line column-alignment property, -with composition - pinned as interim behaviour (hardcoded 8-multiple stops marked temp in source) and deliberately retained for possible future repl editbuf use. - ansi/grepstr.test (9): return modes incl summarydict (linemap pinned always-present; -help claims -n-only - reconciliation deferred to the hygiene pass), exact highlight SGR wrapping, -n numbering with * match counts, invert + empty-highlight strip, -C context with break indicators, capture groups, and tab handling: warns once per call on stderr, a simple single-pass tab line survives with correct highlights. - ns/corp.test (+6): basic-highlight ansistrip equivalence with -syntax none, -n numbering, -untabify spaces exact tab-free expansion + proper 4-element -syntax none list, -untabify unicode markers, the KNOWN DEFICIENCY pin for default -untabify none on a tabbed body (5 grepstr warnings; brace overlays mangle tabbed lines - leaked/shifted close-braces pinned exactly under mocked tabstops; flip deliberately if tab handling is fixed or corp moves off grepstr), and a ::tcl::CopyDirectory -untabify spaces smoke test (tab-free, warning-free, constraint-guarded). src/tests/modules/AGENTS.md punk/ansi + punk/ns index entries updated. Verified: punk/ansi 63/63 and punk/ns 63/63 under Tcl 9.0.3; the three new/extended files green under Tcl 8.7 (10/10, 9/9, 13/13). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
d50d1dd6c5 |
punk::args 0.12.3: fix stringstartswith tail-clause reservation ($tp -> $rv); flip pin
The stringstartswith(*) arm of get_dict_can_assign_value''s multi-member tail-clause reservation walk compared the prefix against $tp (the type string) instead of $rv (the candidate value). Consequences (pinned pre-fix in the previous commit): - a later optional clause mixing literal(...) and stringstartswith(...) members never had genuinely matching trailing words reserved - a greedy -multiple argument swallowed them and the tail clause was silently lost - a prefix text that happened to prefix the literal type string (e.g str vs stringstartswith(str)) wrongly reserved NON-matching words, raising a spurious toomanyarguments overflow One-token fix; allocation_tailclause_ssw_reservation_GAP flipped to the correct expectations (matching words reserved; non-matching words left to the -multiple argument with no error); literal-only and no-match guards unchanged. Known remaining approximation (pre-existing, noted in the buildversion changelog): the walk still requires a literal* member in the tail clause''s typelist to run at all - a stringstartswith-only tail clause is not reserved. Verified: full punk/args suite 231 total / 227 passed / 0 failed (4 intended skips), punk/ns 57/57 under Tcl 9.0.3; allocation.test 10/10 under Tcl 8.7. punk::args buildversion 0.12.2 -> 0.12.3; project 0.12.30 + CHANGELOG. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |
|
|
0f649053ee |
punk::args: characterize stringstartswith tail-clause reservation bug (pre-fix pins)
allocation.test gains coverage for the get_dict_can_assign_value multi-member tail-clause reservation walk (a later optional clause mixing literal(...) and stringstartswith(...) members, guarded from a greedy -multiple argument): - guards (must hold pre and post fix): literal-only tail clause reserved correctly; non-matching trailing words correctly left to the -multiple arg - allocation_tailclause_ssw_reservation_GAP pins the current bug: the stringstartswith(*) arm matches against $tp (the type string) instead of $rv (the value), so matching trailing words are swallowed by the -multiple argument (optional tail clause lost), and a prefix text that happens to prefix the type string (str vs stringstartswith(str)) wrongly reserves non-matching words, ending in a spurious toomanyarguments overflow Verified 10/10 against the unfixed module under Tcl 9.0.3. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 weeks ago |