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
Title broadened in both tiers; Goal/Acceptance gain the -exclude-paths
clauses: expose treefilenames' existing capability on runtests (or an
equivalent post-discovery globmatchpath filter), accumulate semantics
matching -include-paths, exclusion winning over inclusion, a
subtree-exclusion run discovering exactly default-discovery minus that
subtree, and both options pinned by the same regression-suite
combination matrix. Notes record the bundling and the middle-ground
motivation examples.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
User-directed from the G-092 measurement findings: a single
-include-paths value with four deep patterns matched only one subtree,
and repeated -include-paths flags matched zero files, both under the
default *.test tail glob - contradicting the documented accumulate
semantics. Context records the full repro matrix (multi-pattern forms
with explicit tails worked; standalone globmatchpath matched the same
patterns, implicating the treefilenames walk/prune or option-value
shape), the candidate root causes, and the tail-glob workaround. Notes
record that treefilenames already implements -exclude-paths unexposed
by runtests - the planned middle-ground option should be pinned by the
same regression suite.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com