Tree:
43973fa5fd
master
v0.1a
${ noResults }
1555 Commits (43973fa5fdbb68482fdaff9530e5ce7ff7fca73f)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
43973fa5fd |
goals: draft G-179 punk::args discriminator shadowing (opt-in -formselection literalshadow)
Follow-through from G-174: with the walk conserving the tail, 'i a? web
green' honestly reports the web/sample ambiguity - but a?'s implementation
is literal-first else-branch dispatch, so the loose sample form can never
receive a sibling form's literal discriminator word. The declaration
over-admits, and per-type exclusion lists would be cross-referential drift.
G-179 (proposed): definition-level opt-in (-formselection literalshadow) -
among clean matches, a form whose leading discriminator run (literal/
literalprefix alternates or restricted choice sets, form_literal_affinity's
notion) agreed with the supplied words shadows forms accepting the same word
positions only via loose types. Loose-vs-loose ambiguity stays honest,
noformmatch ranking untouched, undeclared definitions byte-identical,
shadowed forms stay introspectable in formstatus; punk::ansi::a? adoption
plus the three cmdhelp.test G-174 presentation-pin flips are in the
acceptance. Related: G-041 (opt-in carve-out from its no-preference
default), G-167 (sibling candidacy filter at the same seam), G-152/G-164,
G-150, G-083, G-174, G-175, G-177, G-072.
Collateral: the G-174 archived follow-on ("tighten a?'s loose sample form"
=> declined) re-dispositioned to => goal G-179 - this goal enacts its intent
by declaration-level means rather than the type-exclusion approach the
decline was about.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
8 hours ago |
|
|
6cc7e8751c |
punk::ns 0.11.1: G-174 cmd_traverse word accounting - doc-lookup walk never drops argument words (project 0.66.3)
The walk behind cmdinfo dropped all but the last trailing word for commands
whose definition's first form is zero-arg with no leaders (the punk::ansi::a?
class): the empty-leader position fell through to the outer per-word loop,
whose exhaustion return reported only the last tail snapshot - dropped words
landed in neither args_resolved nor args_remaining, so cmdhelp's advisory
parse cleanly mis-narrowed 'i a? web green' to the loose sample form with no
failure signal anywhere.
- cmd_traverse: the empty-leader position returns new lane 11 with the
unconsumed tail (remaining shape mirrors the code-3 lane); word-accounting
contract stated at the record comment (conservation; sanctioned exceptions:
ensemble-parameter re-presentation, alias/script currying; first-form-only
inspection recorded as a limit); stale code-7 witness comment corrected
('i namespace which -v x' actually terminates in the code-8 lane).
- cmdflow.test: traverse_final/word_accounting helpers, fixtures
flowmultiform (a?-shaped) / flowmultilead / flownomap / flowplainlead,
lane-code + conservation battery across return lanes 0a,2,X,3,4,6,7,8,9,10,11
(code-7 and code-10 witnessed for the first time), multi-word no-drop pins,
the real-world a? witness, and the first-form-only recorded-limit pin.
- cmdhelp.test: 'a? web green' -return dict (multipleformmatches, formstatus
keys {web sample}) and -return text (web's argument section before sample's)
presentation pins, plus the punk::ns::synopsis underline-marking pin.
- Witness: pre-fix, 8 of the 9 new tests fail (5 cmdflow + 3 cmdhelp);
post-fix punk/ns subtree green on canonical tclsh90s (138 pass, 2
pre-existing gated skips), cmdflow+cmdhelp green on tclsh86ts (86/86).
- G-174 activated on user direction, flipped achieved 2026-08-09 and archived
(entry to GOALS-archive.md, detail to goals/archive/ with Follow-ons);
suite-index DOX updated; project 0.66.3 + CHANGELOG entry.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
8 hours ago |
|
|
955006a014 |
bootsupport promotion: punk::args 0.26.0 (+ templates 0.2.0 layout-sync refresh)
Promotes the minted punk::args 0.26.0 (error_display_value received-word
truncation in validation errors, documented at project 0.66.1) from source
into src/bootsupport, replacing 0.25.2 and re-arming the root-launch
staleness gate: non-interactive root-launched make.tcl commands no longer
abort at the gate, and the 10 maketclbakelist/maketcllibfetch baseline
failures clear (17/17 green after promotion). punk::mix::templates 0.2.0
refreshed in the same pass - the bootsupport modpod picks up the thin-layout
make.tcl carrying the G-151 parse_report landing table (
|
17 hours ago |
|
|
2655f278f1 |
make.tcl dry-run help: parse_report landing table (G-151 follow-on; project 0.66.2)
An accepted 'make.tcl help <subcommand> <cmdline...>' line now stacks punk::args::parse_report's annotated success render - the Argument|Source|Value landing table (received args plus defaults-in-effect) - under the usage render, after the unchanged 'dry-run: line accepted (form N)' line. The interim hand-assembled one-line received-args clue remains only as the catch-guarded degrade fallback (G-030 rule: stale pre-0.18.0 bootsupport punk::args or broken render stack). The gating bootsupport promotion (args 0.25.2 + ansi 0.2.1) already landed, so the render is live. - src/make.tcl: parse_report call + degrade fallback; the two layout copies and the modpod template copy refreshed via the thin-layout sync (make.tcl modules run from src/) - maketclhelp.test: accepted-line pins flipped to landing-row regexps, new reporthdr/default2b pins; 12/12 green (the 10 maketclbakelist/maketcllibfetch failures are the pre-existing non-interactive root-launch staleness-gate baseline - source punk::args 0.26.0 vs bootsupport 0.25.2 - not regressions) - src/AGENTS.md: help bullet now describes the landing table + degrade path - punkproject.toml 0.66.2 + CHANGELOG entry (make.tcl help output is product surface) - goals/archive/G-151-punkargs-annotated-success-render.md: make.tcl follow-on disposition => landed 2026-08-09 Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
17 hours ago |
|
|
3abfe674fa |
punk::args 0.26.0: bound received-value display in validation error messages (G-151 follow-on)
Serves the engine's 'truncate/summarize values in error messages' todo (G-151 lean 5, explicitly deferred from that goal's acceptance). New private::error_display_value wraps the G-151 report_display_value / ansistring TRUNCATE machinery (string mode: single-line-ize with visible control/ANSI rendering, then grapheme-cap with '...' plus ' (len N)') and is applied at every site interpolating a received word into a validation error message: the check_clausecolumn type/size/range/regexprefail reports, the leaders/values allocation-rejection and choiceviolation/ ambiguous-prefix sites, the multi-value clause echo, the -allow_ansi character-view (previously unbounded ansistring VIEW), and the Unexpected-option unknown-flag word. Width cascade: definition-level '@cmd -reportvaluewidth' > built-in 48; 0 = no cap (define -help documents the extension). Display-only: -badarg/-badval errorcode fields keep the raw words. Safety properties: a short plain value (within budget, no C0/C1/DEL content) displays byte-identical via a cheap fast path - important both for the existing message pins (all held unchanged) and because check_clausecolumn builds candidate messages for type alternatives that may never be raised; and the helper catches-and-degrades to the plain non-ansistring fallbacks, since punk::ansi loaded without punk::lib dies in ansistring TRUNCATE (RANGE calls punk::lib::lindex_resolve) - an error message must never die on its display helper. parse_report's own value cells retain that uncaught exposure (pre-existing, success-side). validation.test +4 pins (long-value truncation with raw -badval retention, multiline single-line-ization, @cmd -reportvaluewidth cap, unexpected-option word truncation with raw -badarg retention). Args subtree 415/0 on tclsh90s (9.0.5) and tclsh86ts; full suite at the recorded 13-failure environment baseline (maketclhelp re-verified 12/12 with a real tclsh on PATH). Minted modules/punk/args-0.26.0.tm. Project version 0.66.1 (patch: kit-shipped error-display behaviour) with CHANGELOG entry; G-151 archive follow-on disposition flipped to landed. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
18 hours ago |
|
|
585ce13f54 |
runtests: clear read eofchar on multiproc capture reads (8.6 ctrl-z truncation)
A native windows Tcl 8.6 runner's text channels default the READ eofchar
to ctrl-z (\x1a; the default 9.x removed), so the multi-process child
capture read in runtests_run_child_process silently truncated child
stdout at the first \x1a. The MULTISHELL polyglot deliberately carries a
ctrl-z tailblock and the scriptwrap/dtplite suites echo polyglot content
into their output, so every such file misreported as missing-cleanupTests
with zero observed tests under an 8.6 -jobs run (children completed and
exited 0; byte-proven: text read 8689 chars of a 256523-byte capture,
first \x1a at offset 8762 - full via binary read). Fix: fconfigure
-eofchar {} on both the stdout and stderr capture reads, making 8.6 match
the 9.x read semantics (translation stays auto). Immune paths that
obscured the mechanism: 9.x parent, MSYS/unix-mode 8.6, singleproc
(in-process runx capture). An apparent file-count/concurrency dependence
during diagnosis was a red herring - the 'passing' repros had -jobs
placed after the trailing file-tail globs, silently running singleproc.
New regression pin runner/testsuites/capture/ctrlz_capture.test emits a
\x1a byte before its test result, so a truncating runner turns it into a
missing-cleanupTests warn in any future multiproc run.
Verified: scriptwrap family under tclsh86ts -jobs 8 went from 5 warned
files / 0 counted tests to 10 counted (9 pass + pre-existing isunix
skip); scriptwrap+punkboot+binscripts neighbourhoods now count 123 tests
on the 8.6 leg, identical to the 9.0 leg (18 tests across 6 files were
previously invisible); runner suites incl the pin pass on 86ts and 90s;
9.0 behaviour unchanged.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
19 hours ago |
|
|
f4953b86fc |
test suites: lib-tier package deps probed to constraints (json, sha1, struct::stack)
Seven suites hard-required packages that only a lib-tier-provisioned runner interpreter supplies (the suite-built/runtime-store tclsh carry tcllib in their own library tree; runtests deliberately propagates the runner's [info library] into the child auto_path). On unprovisioned hosts (e.g. a PATH tclsh86 without tcllib) each such file died wholesale: load-time requires errored the file (pathcmd, argparsingtest_compare, maketcllibfetch, offsetstyle - the struct::stack cases via vendored tomlish's own require) and scriptwrap's lazy 'package require tomlish' (_read_scriptset_wrap_tomlfile) errored tests mid-body (runtimecmd_roundtrip, multishell sentinel, dtplite checkfile tests). All are now feature-probe constraints in the established have_tclcoredocs style: - pathcmd.test: jsonAvailable probe wired (was hardcoded 1 and attached to no test) gating the json round-trip test - argparsingtest_compare.test: jsonAvailable gating compare_json - maketcllibfetch.test: have_sha1 gating the artifact+sha1sums+server fixture portion (the config/env scaffolding still builds, so the trustgate and no-config tests run) and the file:// mirror test - offsetstyle.test: have_tomlish gating the build-baseline test (its G-165 exemption logic reads mapvfs.toml); the six probe tests keep running, the file-level mapvfs read already catch-degrades - runtimecmd_roundtrip.test / multishell.test: have_tomlish gating the wrap tests (multishell's wrapok fixture already catch-degrades; the sentinel keeps failing loudly on provisioned runners) - dtplite.test: tomlish folded into the existing havescriptwrap probe Verified: provisioned runners unchanged (86ts/90s green, only pre-existing isunix/parser-availability skips); PATH mingw tclsh86 (json-less, struct::stack-less) runs all seven files with visible constraint skips and zero failures; sha1-less behaviour proven via a package-unknown-cleared harness (trustgate+no-config pass, 6 fixture skips); testbody_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
19 hours ago |
|
|
c2938e2dcf |
punk/ns tests: 8.6/8.7 leg conditioning (feature probes + divergence pins)
The six 8.6/8.7 failures in nslist.test/nsprimitives.test were
never-green pins (authored 2026-07-14/19, before native-8.6 runner
support existed), not regressions. Three causes, conditioned without
module changes since both module behaviours are documented intent:
- 'info vars' in a namespace context includes globals on pre-TIP-278
cores: nseval_ifexists_weird pattern-narrowed to 'info vars m*'.
- nstree_raw weird-children recursion: the composed :🅰️::odd string
form is unresolvable as a fresh string on ALL cores (probed
8.6.18/8.7a6/9.0.5); the 9 leg passes only because 'namespace
children' values carry a resolved internal rep that survives the
recursion. New capability probe weirdns_children_recursable gates the
literal-listing pin, with a portable plain-tree test and an
inverse-gated recursion-failure pin.
- get_ns_dicts classification needs ::tcl::info::cmdtype (8.7+): the
8.6 fallback deliberately returns na for renamed aliases, coroutines
and native builtins. have_infocmdtype gates the four dependent tests
(cor tag split out so the other five tag pins keep the 8.6 render
path covered) and nslist_classification_no_cmdtype_fallback pins the
divergence.
Verified green: 8.6/8.7/9.0 x -jobs/singleproc, ns subtree 131 total
0 fail (8.6: 5 skip, 8.7/9.0: 2 skip, all by constraint design);
testbody_lint clean.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
21 hours ago |
|
|
bd9c0feade |
runtests: 8.6 -jobs children get the punk::lib compat guard (lpop)
Multi-process children ran without the guarded punk::lib 0.5.1- require, so under a native 8.6 runner every suite whose module parses via punk::args::parse died with 'invalid command name "lpop"' - the lean-children cleanup ( |
21 hours ago |
|
|
8078f22c42 |
bake output trees: r2 payload materialization into kit .vfs folders
The 0.66.0 bake's VFSPAYLOAD phase materialized the r2 lib tier into the tracked kit .vfs trees (the G-115 in-folder class G-171 will move to staging): per tcllib2.0 tree the five gate-repaired pkgIndex.tcl files, the r2 embedded punkbin-artifact.toml (upstream_repairs pointer), and punkbin-upstream-repairs.toml newly tracked - the shipped divergence from upstream is now self-describing IN VCS; tcllibc trees take the r2 dll + teapot + record (zig dlls are not bit-reproducible - the recorded reason revisions bump). Twelve vfs trees, all content derived from the committed libpackages.toml r2 pins via bin/packages. Step-(9) close of the 0.66.0 release cycle. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
cf669c85d7 |
src/AGENTS.md: make.tcl driving-interpreter guidance (tcllibc accelerators)
Agent-agnostic record of the 2026-08-08 pitfall: digest-heavy make.tcl
commands (packages/modules/libs, libfetch, vfscommonupdate, bake) hash via
tcllib sha1 and run ~460x slower without the tcllibc critcl accelerator -
measured: a packages mint burned 458+ CPU-seconds unfinished under the bare
zig suite tclsh, then completed both promotion phases in minutes under an
accelerated interpreter. Guidance: drive make.tcl with a machine tclsh
carrying tcllib+tcllibc or a punk family runtime; the bare suite tclsh
remains canonical for TEST runs only. Includes the punkcheck dead-pid lock
recovery for mints killed on this account. Also corrects the dirty-run
grace countdown doc to 4 seconds (changed
|
1 day ago |
|
|
de4c69b68e |
project 0.66.0: repaired tcllib in kits + tdom in 905 kits + G-176 arc deployed
Pre-bake version bump (release step 2; the bake asserts it via -expect-projectversion). The 0.66.0 CHANGELOG entry covers what the rebaked kits ship: pkgindex_gate-repaired tcllib with the self-describing punkbin-upstream-repairs.toml manifest (upstream tkt 523f7e0556 - rest and four siblings finally requirable), tdom 0.9.6 restored to the 905-era punk kits, and the G-176 command-documentation arc arriving in deployed shells via the promoted coherent set. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
760882aad3 |
vfscommon promotion: G-176 coherent set + r2-era layout/templates sync
Release-step-(9) commit of the Step 5 promotion outputs (packages mint +
vfscommonupdate, driven by the tcllibc-accelerated family runtime):
_vfscommon.vfs module swap commandstack 0.7.1->0.8.0, punk 0.2.8->0.3.0,
ansi 0.2.0->0.2.1, args 0.18.0->0.25.2, libunknown 0.2.4->0.3.1,
ns 0.9.3->0.11.0, moduledoc tclcore 0.4.0->0.4.2 + punkboot 0.3.1->0.3.2;
templates-0.2.0.tm modpod repacked; the three layout-store make.tcl copies
re-synced (verified byte-identical to src/make.tcl - carries the
libunknown package-provide guard swap
|
1 day ago |
|
|
7525bc3eba |
libpackages.toml: consume lib tier r2 (gated tcllib + repairs manifest)
All five declared artifact pins bumped r1 -> r2 - the deliberate consumer-side half of the 2026-08-08 publish (punkbin b5b5149): tcllib2.0-tcl8/tcl9-r2, tcllibc-tcl8/tcl9-r2 (win32), tcllibc-tcl9-r2 (linux). Header comment updated to name the r2 vintage (pkgindex_gate-repaired trees shipping punkbin-upstream-repairs.toml, upstream tkt 523f7e0556). Verified live: user-run canonical libfetch materialized the r2 trees into bin/packages with the manifest present and rest indexed at 1.8. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
b0a4c6ef29 |
buildsuites publish riders: librev default -> 2 (published-state record) + record path fix
librev defaults bumped 1->2 in both recipes with repaired help text (was "nothing published yet" while r1 had been published since 2026-07-30 - the manual-drift failure mode recorded in G-171's publish follow-on); the help now states the convention: the default IS the committed record of published state, bumped in the same work unit as each publish. Family-record comment fix (tcl90): the repairs-manifest pointer is artifact-relative - lib/tcllib<ver>/punkbin-upstream-repairs.toml in the mounted image (the attached zip roots at the staged base/, so the previous base/lib/... path named a location that does not exist to a reader inside the runtime). Probe-caught before publish; family kits rebuild before the replace. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
05638877d3 |
G-171 note: publish command owns artifact-revision derivation
Extends the dirty-bake provenance follow-on's publish-command endpoint with the -r<N> derivation duty (user question 2026-08-08: must -Dlibrev be manual?): the build recipe cannot safely self-derive (deliberate-publish discipline, no configure-time mutable-state inputs, rev-inside-artifact means comparison must build AT the published rev and sha1-compare); publish verdicts current / bump to max+1 / alpha in-situ replace, asserted on a checked claim. Records the recipe-default-as-published-state convention (familyrev precedent) and librev's observed drift as the manual failure mode - default+comment repair due at the r2 publish. goals_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
988c7868fd |
G-171 amendment follow-up: GOALS.md Scope mirror sync + G-176 archive marker
goals_lint caught both: the index Scope mirror must match the amended detail Scope (index carries a mirror the amendment commit missed), and the new alternatives bullet's G-176 reference needed its achieved/archive marker. Lint now fully clean, no findings or warnings. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
e42587cd79 |
G-171 amendment: runtime-content masks (declared kit-level battery demotion)
Extends the proposed goal with Approach 11 + matching Goal/Scope/Acceptance clauses and a Context assembly finding (2026-08-08): zip-kit bake EXTRACTS the runtime's attached vfs into the per-kit merge tree, so runtime batteries are structurally maskable - but supersedes/replace run in the VFSPAYLOAD phase before extraction and never reach them, so a bi-runtime kit with a lower-versioned payload battery ships both copies and highest-wins picks the runtime's. The amendment: mapvfs.toml kit-entry runtime_excludes applied at merge time after extraction - the payload version wins by absence of competition. Guardrails (boot-critical refusal, smokerequire proof), provenance (mask = declared config, punkkit-stamp runtime_masks key, no-volatile-fields safe; runtime's own record never edited), zip-lane first. Alternatives recorded: require-time pinning via the managed ::package override, runtime-variant proliferation. goals_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
8db289fd57 |
punk9wintk905.vfs: carry tdom 0.9.6 (punk kits need rest-class tcllib deps)
The 905-era vfs was created without tdom while its predecessors (punk9wintk903/90b2) and the bi vfs (punk9win_for_tkruntime) all carry it - so punk905/punk9_beta kits could not load punk::netbox-class libs and 'package require rest' failed on the missing dep before ever reaching the tcllib pkgIndex skew. User direction: bi kits AND plain punk executables both carry tdom (bi may stay conservative, punk kits may advance later). Copied verbatim from punk9win_for_tkruntime.vfs (slim variant, no HTML docs, dual-generation pkgIndex; its tcl9tdom096.dll is live-proven in the deployed punk9bi_beta today). Reaches kits at the next bake; CHANGELOG entry rides the pre-bake version bump. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
0c090fa50b |
buildsuites: gated-tree repairs manifest + provenance-record pointers
Closes the tcllib_checkout honesty gap: a gated tree's shipped content is its checkout PLUS the pkgindex_gate repairs, but no record travelled with the divergence. pkgindex_gate.tcl (both suites, byte-identical) now writes punkbin-upstream-repairs.toml at the gated tree root after both gate checks pass - the applied-repair enumeration ($repaired, sorted), the upstream ticket URL (promoted to data as UPSTREAM_REF), deterministic content only. Both artifact consumers carry the tree verbatim, so the enumeration ships inside every kit and lib zip adjacent to the divergence it explains; no manifest is written on gate failure (fixture-verified both directions). Records point rather than duplicate (single owner = the gate's allowlist; the manifest is written from the post-verification applied set, so it can never drift): library_artifacts.tcl [provenance] gains upstream_repairs = "punkbin-upstream-repairs.toml" when the package folder carries the manifest; build905.zig family records gain tcllib_gated = true with the resolved base/lib/tcllib<ver>/ manifest path (build86 emits no family records - covered via the shared tools). Verified: gate fixture with all five recorded defects + clean module (repairs + manifest exact); info-complete on both Tcl tools; zig ast-check + extracted-template compile render proving 18-arg format arity. Cross-suite tool copies byte-identical. No project bump (buildsuite-only). Effect materializes at the r2 rebuild chain - r2 records honest from birth. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
5c47f3b97f |
bootsupport promotion: G-176 coherent set + make.tcl libunknown guard follow-on
Release-step-(9) commit of the src/bootsupport refresh (user-run 'make.tcl
bootsupport'): commandstack 0.7.1->0.8.0, punk 0.2.8->0.3.0, ansi
0.2.0->0.2.1, args 0.18.0->0.25.2, moduledoc tclcore 0.4.0->0.4.2,
libunknown 0.2.4->0.3.1, ns 0.9.3->0.11.0 - all seven verified
byte-identical to the minted modules/ tree. make.tcl regains committed
provenance for the tooling it boots from; the staleness gate is satisfied
by committed content again.
With it, at the G-176 follow-on's own due point ("before or with the
bootsupport/kit promotion"): the libunknown skip-guard swapped from 'info
commands ::punk::libunknown::package' (a proc the 0.3.x
commandstack-managed install no longer creates) to a 'package provide
punk::libunknown' probe - satisfied by every vintage's boot-site source
(verified in 0.2.4 and 0.3.1; tclsh-driven boot smoke green). Disposition
flipped to landed in the archived goal; goals_lint clean. No project bump:
promoted content already versioned (0.63.0-0.65.0 arc), guard swap is
interface/output-unchanged make tooling internals.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
1 day ago |
|
|
2ec08535a8 |
G-171 note: dirty-bake provenance indication - follow-on candidate
Records the 2026-08-08 assessment as a live-tier Notes item (becomes a Follow-on line at the flip, per goals/AGENTS.md - live goals carry no Follow-ons section): near-term tree_state field in the advisory kit sidecar surfaced by bakelist/BAKE SUMMARY/buildinfo; endpoint a publication-side content-addressed manifest (kit sha1 -> producing commit, absence IS the indication) sequenced after G-171's records-free-clone reproducibility lands; stamp/payload and filename homes rejected (determinism principle, name-keyed machinery). goals_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
cc92078c44 |
make.tcl launch-site steering (red) + countdown to 4 (project 0.65.2)
The staleness fix block now ends with a red-highlighted steer back to the project root for the remaining steps (vfscommonupdate/bake are canonically root-launched on the refreshed bootsupport snapshot, which also re-arms the staleness check), and the src/-launch banner carries the same red canonical-mode steer plus a repair/testing-is-fine line - so the mode is self-describing however the user arrived in src/. Early-site colour via the ::punkboot::sgr gate (NO_COLOR/force/tty precedence, piped output ESC-free; verified forced-colour and NO_COLOR renders). Dirty-src proceed countdown extended to 4 seconds (user change). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
c8b51bc49a |
G-171 note: staleness-message emitter seam for Approach 10
Records that the stale_bootsupport gate cited as the layout-store report's
shape template now emits via the shared punkboot::lib::bootsupport_stale_warning
helper (
|
1 day ago |
|
|
8aa824ee88 |
layout store sync: propagate make.tcl staleness-gate message (0.65.1) to project layouts
sync_layouts propagation of the reworked bootsupport-staleness warning
(
|
1 day ago |
|
|
b729ce07d7 |
make.tcl staleness-gate message: explain launch-site module precedence (project 0.65.1)
The recommended fix (rerun modules && bootsupport from src/) read as circular when the gated command was itself modules or bootsupport. The warning now names the launch directory, contrasts src/ vs elsewhere module precedence (the stale bootsupport copies are the code executing the current run), special-cases the repair commands with a NOTE, and prints the resolved src path as a copy-pasteable fix line. Shared emitter (punkboot::lib::bootsupport_stale_warning) for the pre-dispatch gate and the check report tail. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
1 day ago |
|
|
71e3c96387 |
G-177 + G-178 drafted (proposed): punk::args scalability - cost decoupling and multi-provider safety
Drafted from a measured scalability review asking what breaks if every command - including third-party libraries - carries punk::args documentation. Baseline probes (punk91, 58 registered namespaces / 693 definitions) found three cost centres and one governance gap; the two goals split them by kind. G-177 (engine, measurable): the resolved-spec caches key on the whole raw definition text (~args:2152, the author's own todo), so ~4 full-text hashes ride every parse call - an isolation probe shows the ENTIRE per-call growth with documentation size sits in those keys (220 B definition 28.8us vs 9776 B definition of identical argument shape 56.8us; resolve 1.5 -> 29.6us). Registry membership is lists with a nested-loop ldiff behind a length-equality early-out that never fires in a stock session (registered=58 loaded=60 - argdoc namespaces enter loaded_packages un-registered and registration is not deduped), so update_definitions costs 9.3us at R=100 and 2515us at R=2000 while being called per ensemble subcommand. The scan phase is eager and global (15us per definition). Acceptance is six machine-independent ratio pins (1.15x doc-size independence, 2x registry-size independence, early-out liveness plus its false-positive, O(1) scan, 40% raw-text residency drop, byte-identical corpus renders) rather than absolute times, so the suite pins the complexity class and survives hardware changes. G-178 (governance, policy): flat global id namespace with silent collisions (the "last will silently win" todo at ~args:5137), non-idempotent registration into a foreign namespace variable, no definition format-level declaration, and third-party help text that is tstr-evaluated with -allowcommands at resolve time - documentation that runs code. Split from G-177 per the goals/AGENTS.md rule that a goal must be summarizable by title and Scope alone. Overlap survey (goals_xref paths + score): Related lines to G-175 (disjoint - it owns how many times a render resolves, G-177 owns what one resolve costs), G-044/G-050 (latency consumers), G-075 (shared id-lookup path), G-167 + G-056 (both deliberately change render output, which G-177 pins byte-identical - whichever lands second re-baselines the characterization), G-046 (archived predecessor whose display-field deferral is why the residual doc-size tax is purely the cache keys). No archived follow-on disposition required flipping. goals_lint clean (81 active-index goals / 97 archived). Claude-Session: https://claude.ai/code/session_01Y5vEJUZkD4p8jmEFEBVhLi Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
2 days ago |
|
|
7787f0e06e |
G-176 archive: Follow-ons section brought to contract (single-line items, last section) - the two open items now enumerate in goals_followons
The achieved flip's step (c) was written non-conformant: the two deferred
items were multi-line prose bullets with trailing '=> open' markers, and
the '## Follow-ons' section sat before '## Notes'. The Follow-ons
contract (goals/AGENTS.md, goals-system v4) requires one item per line at
column 0 ('Follow-on: <item text> => open') in a '## Follow-ons' section
that is the LAST section of the archived detail file -
goals_followons.tcl enumerates only grammar-conformant lines, so the
items were invisible to the report (and goals_lint only validates lines
that BEGIN with 'Follow-on:', so nothing flagged them).
Both items (boot-site commandstack pre-sourcing; make.tcl skip-guard
modernization) now appear in the goals_followons OPEN section. Item
content unchanged in substance - compressed to single lines, with the
now-moot scope-amendment caveats dropped (an archived goal's follow-ons
are enacted via new goals or direct landing per the disposition
vocabulary).
Flip-guidance audit against goals/AGENTS.md prompted by the miss: Status
grammar, Progress evidence, pure-rename archive moves, index/archive
records and the live-tier reference sweep (no G-176 references exist in
goals/*.md or GOALS.md) all check out; the Follow-ons grammar was the
one non-conformance.
goals_lint clean (79 active-index / 97 archived); goals_followons
enumerates both G-176 items as open.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 days ago |
|
|
8fa716b62b |
G-176 achieved: override hints + 'package epoch' documented via stack-tied doc block (punk::ns 0.11.0, punk::libunknown 0.3.1; project 0.65.0)
Increment 4 (the final increment) + the achieved flip.
punk::ns 0.11.0: cmdinfo gains an 'overridden' result key - a second axis
beside cmdtype/unavailable (the G-166 pattern) reporting the LIVE
commandstack override state of the base command: one {renamer <string>
docids <list>} dict per stack record (bottom-up), docids being the
punk::args ids of doc blocks the record attached via 'rename_command
-punkargs' (derived with punk::args::rawdef_id). Guarded live query - no
hard commandstack dependency, empty when commandstack is not loaded,
never cached so it is correct as stacks change. cmdhelp surfaces it: the
table/string renders lead with a plain "note: '<cmd>' is currently
overridden/extended via commandstack by: <renamers> (override-attached
docs: '<ids>')" line, -return text leads with an OVERRIDDEN: line (below
UNAVAILABLE when both apply), -return dict carries the key on all return
shapes incl the undocumented fallback.
punk::libunknown 0.3.1 (renamed from 0.3.0): the 'package epoch'
subcommand is now DOCUMENTED - a substitution-free doc block with the
space-form id {::package epoch} rides the override's commandstack record
via -punkargs: mirrored for lazy pickup when punk::args loads after init
(normal early boot), defined immediately when punk::args is present, and
removed with the record by any removal path. 'i package epoch' renders
real usage (all six grammar forms) - the doc gap that motivated the whole
arc, retired. init's require tightened to 'commandstack 0.8-': a
pre-mechanism stable copy fails pointedly at init instead of mid-call
with a usage error (found via shadowing.test, whose require-based
children needed 'package prefer latest' - the default stable preference
picks a stale stable bootsupport commandstack over the alpha-versioned
dev copy).
End-to-end verified: 'i package epoch' renders the epoch doc; 'i package'
leads with the note naming punk::libunknown and '::package epoch';
-return text/-return dict carry OVERRIDDEN:/the structured key;
restore_original ::package removes doc and note.
Tests: cmdhelp.test gains 2 hint pins (documented-command note incl docs
clause + dict axis; doc-less-proc autodef render leading with the note,
OVERRIDDEN: text lead, note clearing on unwind) and its two key-list pins
(cmdhelp_cmdinfo_result_shape, cmdhelp_return_dict_valid) flip
deliberately with the new key - exactly as they did for G-166's
'unavailable'. packageoverride.test gains the flagship pending-path pin
(epoch doc mirrored pre-punk::args in path-cleared children, lazily
defined on punk::args arrival, removed on unwind) and its pko_probe
injects ::PKO_SRCMODULES. shadowing.test children set 'package prefer
latest'. src/tests/modules/AGENTS.md punk/ns + punk/libunknown bullets
updated.
G-176 flipped ACHIEVED 2026-08-08: every acceptance clause met across the
four increments (characterise -> migrate -> -punkargs mechanism -> hint +
flagship docs). Detail file archived to
goals/archive/G-176-commandstack-doc-integration.md with its two
boot-site Follow-ons kept open (commandstack pre-sourcing at the
libunknown-style boot sites; make.tcl skip-guard modernization - due by
the 0.3.x/0.8.0 bootsupport promotion). GOALS.md entry removed;
GOALS-archive.md record added; the one tree reference
(packageoverride.test header) swept to the archive path.
Project 0.64.0 -> 0.65.0 + CHANGELOG.
Suites: libunknown+ns+commandstack+loadedlib 216/216; full modules tree
1354 total / 1343 pass / 11 constraint-skipped / 0 fail (zig-built
tclsh90s 9.0.5); testbody_lint 1707 clean; goals_lint clean (79
active-index / 97 archived); make.tcl projectversion consistency OK.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 days ago |
|
|
ad0489b881 |
commandstack 0.8.0: rename_command -punkargs stack-tied doc blocks (G-176 increment 3; project 0.64.0)
rename_command accepts a new leading option '-punkargs
<list-of-definitionlists>' attaching punk::args doc blocks to the
rename's stack record - e.g documenting a subcommand the override adds,
with space-form ids such as {::package epoch}. Each element is one
definitionlist exactly as given to punk::args::define (the same shape as
a PUNKARGS variable element).
Lifecycle: docs attach only when the rename lands (aborted renames
return early) and are LIVE while the record is on the stack. The detach
hook sits at remove_rename's doomed-record site - pop_rename,
remove_renamer and restore_original all funnel through it - so every
removal path removes the docs with the record.
Works whether or not punk::args is loaded at rename time: deflists are
mirrored in a new ::commandstack::stackdocs namespace registered inert
into ::punk::args::register::NAMESPACES at module load (punk::args need
not be present - the early-boot renames precede it), so a later-loading
punk::args picks them up lazily; when punk::args is already present they
are ALSO defined immediately (a namespace already consumed into
loaded_packages never lazy-loads later appends; redefinition is
idempotent). Detach removes one mirror occurrence per deflist and
undefines via punk::args::undefine_deflist (deflist-keyed - commandstack
never parses ids; never-defined deflists skip silently). Supported
shape: one live record per doc id (same-id declarations in two records
shadow; removing either removes the doc).
The record carries the deflists under a trailing 'punkargs' key - the
append-only key-order contract is preserved (token idx 0-1, renamer idx
2-3). The leading-option parse is generalised: -renamer/-punkargs in
either order, both leading-only, non-dash word ends option scanning so
misplaced options raise the pointed error. stackdocs state follows the
0.7.1 reload contract (info-exists guarded; registration idempotent
across re-source). commandstack::help and the rename_command argdoc
document the mechanism; the In-tree users line gains punk::libunknown
(the increment-2 migration).
commandstack.test: 5 new pins (docs live with the record incl key-order
assertions, all four removal paths detach, the pre-punk::args pending
path in a bare child that loads punk::args afterwards and lazily
consumes the registered mirror, reload contract on mirror + single
registration, option positions in either order + pointed misplacement) +
2 existing G-160 message pins updated to the generalised
usage/misplacement wording (behaviour contracts unchanged). Suite 46/46.
src/tests/modules/AGENTS.md commandstack bullet updated; goal Progress
entry added. Project 0.63.0 -> 0.64.0 + CHANGELOG.
Suites: commandstack 46/46; full modules tree 1351 total / 1340 pass /
11 constraint-skipped / 0 fail (zig-built tclsh90s 9.0.5);
testbody_lint 1704 clean; goals_lint clean (80 active-index / 96
archived); make.tcl projectversion consistency OK.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 days ago |
|
|
72725deecb |
tcllib pkgIndex gate in both buildsuites: upstream ifneeded/provide skew (rest 1.7 vs 1.8) repaired before it reaches kits
'package require rest' fails in every punk kit built from stock tcllib: modules/rest/pkgIndex.tcl indexes 1.7 while rest.tcl provides 1.8, so Tcl runs the 1.7 ifneeded script, the file provides 1.8, and the require dies with "attempt to provide package rest 1.7 failed: package rest 1.8 provided instead". No version request can satisfy it. Upstream regressed this in tcllib checkin [0b3dd048f8] (2025-07-16), which bumped the provide and left pkgIndex.tcl (and rest.man) at 1.7; still unfixed on trunk/master, so the pin cannot be moved past it. Reported as https://core.tcl-lang.org/tcllib/tktview/523f7e055647611328efa2539717023d18b99ccd Four siblings share the class in the shipping tree: doctools::toc (2 vs 2.1), math::filters (0.3 vs 0.4), nettool (index sources a nonexistent nexttool.tcl), and tcl::chan::std (1.0.2 vs 1.2 - latent only, punkshell's own lib/virtchannel_base copy shadows it). tools/pkgindex_gate.tcl (byte-identical copies in both suites) sits between the tcllib installer output and the install tree. The index follows the file: the provide is what executes, so rewriting a file's provide down to its indexed version would misrepresent the code. It is a gate, not a silent fixer - an unrecorded defect fails the build (new upstream breakage and a genuine version bump are indistinguishable here, and the difference is a human decision), and an ALLOWLIST record matching nothing also fails, meaning upstream fixed it and the record must go. build905.zig had TWO consumers of the raw installer output - the install prefix and the kit-family base/lib/tcllib<ver> copy. Both now take the gated tree; repointing only the install would have left every kit broken while the fix looked applied. Verified: 440 indexed loaders checked, 5 repaired, exactly 5 single-line diffs and nothing else touched; an independent re-audit of the repaired tree reports 0 mismatches; rest 1.8, doctools::toc 2.1, math::filters 0.4 and nettool 0.5.4 all require cleanly against it; both gate failure arms exercised; the tool runs identically under Tcl 8.6.18 and 9.x; both zig recipes compile and construct their graphs under the pinned zig 0.16.0. No full suite rebuild was run - the fix reaches kits only after a rebuild, lib-tier r2 emission, publish, libfetch and bake. No project-version bump: buildsuites are a non-shipped surface. Claude-Session: https://claude.ai/code/session_01DeQ2aPnbsinpFABUTYK34k Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com |
2 days ago |
|
|
a7bc62c3fb |
punk::libunknown 0.3.0: ::package override installs via commandstack (G-176 increment 2; project 0.63.0)
The ::package override (the 'epoch' subcommand and controlled 'forget') now installs via commandstack::rename_command -renamer punk::libunknown instead of the former 'rename ::package :📦:' + namespace-import mechanism. Both live ::package overrides (this and punk::packagepreference's) now share one managed stack whatever the install order - stack removals and third-party renames re-link correctly instead of operating on the wrong command (previously commandstack's ::package stack believed the packagepreference wrapper was live while libunknown's unmanaged import actually was; restore_original would have stranded :📦:). Migration deltas (exactly the set enumerated in the goal Context): - the override body runs at :: - the four bare epoch_incr_pkg/epoch_incr_tm calls are fully qualified (the old namespace-import execution context is gone) - the dead 'variable has_package_files' declaration dropped (its only use was already commented out; the module-load probe stays) - the two :📦: delegation sites (forget arm, default arm) now delegate via COMMANDSTACKNEXT; :📦: no longer exists (nothing in the tree called it) - init does 'package require commandstack' (a no-op when already provided - e.g whenever punk::packagepreference::install ran first, as in punkshell boot; resolvable via tm paths in every other real init context - bootsupport and the common vfs both carry commandstack-0.7.1) - re-entry guard is now a stack query for the punk::libunknown record (same 'already done' notice; the old ::punk::libunknown::package proc-existence check tested a proc that no longer exists) - init argdoc reworded; file renamed libunknown-0.2.4.tm -> libunknown-0.3.0.tm (git mv + fossil mv) with Meta/manpage/provide-block version updates and a changelog entry per the in-file bump procedure. Behaviour of every subcommand arm is unchanged: all increment-1 BEHAVIOUR pins in packageoverride.test passed byte-identically; only its four MARKED-TO-FLIP install-shape pins flipped as fenced (origin ::package, no :📦: residue, managed stack records - 1 solo, 2 in both packagepreference interop orders). discovery.test and packageoverride.test child interps now pre-source the source-tree commandstack by path (their tm paths are cleared); libsearch/shadowing children resolve commandstack via inherited parent paths and needed no changes. Two out-of-scope items recorded as open Follow-ons in the goal (Scope amendment needed if pursued): boot-site commandstack pre-sourcing (punkboot core.tcl / make.tcl / punk::repl / punk::lib child-seeding - to preserve the minimal-untracked epoch intent exactly) and make.tcl's 'info commands ::punk::libunknown::package' skip-guard modernization (old kits still satisfy it; switch to a package-provide check before or with the 0.3.0 bootsupport/kit promotion). Goal Scope mirrors updated to the new filename (rename anticipated in the Scope text). Project 0.62.2 -> 0.63.0 + CHANGELOG. Suites: libunknown tree + loadedlib 42/42; full modules tree 1346 total / 1335 pass / 11 constraint-skipped / 0 fail (zig-built tclsh90s 9.0.5); testbody_lint 1699 clean; goals_lint clean (80 active-index / 96 archived); make.tcl projectversion consistency OK (and that run itself exercised the bootsupport-0.2.4 transition path live). Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
642fb265ea |
G-176 increment 1 + active flip: ::package override characterisation - the pre-migration safety net (packageoverride.test, 11 pins)
G-176 marked active (user-directed). New src/tests/modules/punk/libunknown/testsuites/discovery/packageoverride.test pins the CURRENT punk::libunknown ::package override ahead of the increment-2 migration onto commandstack::rename_command. BEHAVIOUR pins (must stay green byte-identically through the migration): 'package epoch tm|pkg' single-arg forms, indexed '<which> <index> ?key?' queries, the four error arms, the filtered forget arm (real-ifneeded forgotten, no-ifneeded filtered out, tcl/Tcl/tcl::oo/tk denied, mixed lists partially applied), abbreviation acceptance (ep/epo/epoc + fo routing, with the parked builtin's rejection of 'ep' pinned as the override's deliberate delta), delegation pass-through, and the re-init no-op contract (stderr notice captured via a child ::puts shim). MARKED-TO-FLIP pins (comment-fenced to the increment-2 commit and no other): the install shape (::package origin = the ::punk::libunknown::package namespace import; :📦: parked and functional) and the two-override packagepreference interop children in BOTH real-world install orders (punkshell's pkgpref-first: stack count 1 + import origin; make.tcl's libunknown-first: stack count 1 + ::package proc origin). Children are fresh interps sourcing the source-tree libunknown/commandstack/packagepreference by path via a shared highest-version locator (discovery.test pattern). All 11 pins green on the first run against the live implementation. Tests AGENTS.md index updated; goal file gains its Progress entry. testbody_lint 1699 clean; goals_lint clean (80 active-index / 96 archived); modules tree 1346 total / 1335 pass / 11 constraint-skipped / 0 fail (zig-built tclsh90s 9.0.5). Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
b10abcbae0 |
G-176 drafted (proposed): commandstack doc integration - stack-tied overrider argdocs, override hints, libunknown package-override migration
Four-increment arc from the 2026-08-08 feasibility investigation:
(1) characterise the untested arms of the current punk::libunknown
::package override (epoch single-arg/indexed forms + error arms, the
entire forget arm, abbreviation acceptance, delegation, re-init guard,
packagepreference interop in both install orders; install-shape pins
marked to flip), (2) migrate that override onto
commandstack::rename_command (one managed stack for both live ::package
overrides - cures the restore_original/wrong-command latent hazard of
the current unmanaged mix), (3) rename_command -punkargs stack-tied doc
blocks (attach at the single rename site, detach at the remove_rename
choke point every removal path funnels through; stackdocs registered
namespace covers renames performed before punk::args loads), (4)
cmdhelp/cmdinfo override-in-place hint (G-166-style second axis, live
get_stack query, no hard dependency) + the flagship {::package epoch}
doc attachment and the commandstack::help how-to.
Investigation evidence embedded in the goal Context: probe-verified
space-form doc define/resolve/undefine/fallback cycle ('i package
epoch' resolves despite the parent's restricted choices - G-051
space-form jump), record-key append contract, undefine_deflist
primitive, no external :📦: callers, the dead
has_package_files declaration, both real-world install orders.
goals_lint clean (80 active-index goals / 96 archived).
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 days ago |
|
|
b82827d837 |
punk::args 0.25.2 + tclcore moduledoc 0.4.2: qualify ensemble names into ensemble_subcommands_definition - 'i ::tcl::prefix' unqualified-ns warnings gone; G-175 drafted (project 0.62.2)
'i ::tcl::prefix' emitted 12x "warning: update_definitions received unqualified ns: tcl" on stderr (6x for subcommand renders). Root cause: the tclcore moduledoc's @dynamic ::tcl::prefix definition passed the ensemble name to punk::args::ensemble_subcommands_definition UNQUALIFIED ('tcl::prefix'). The generator's space-form id_checks derive namespaces via 'namespace qualifiers' - for a relative multi-component name that yields a non-empty UNQUALIFIED namespace ('tcl') which the empty-qualifier guard ('' -> ::) never catches - and update_definitions warned once per subcommand per resolve. @dynamic definitions re-expand on every resolve and the cmdhelp pipeline resolves the id four times (parse_status spec fetch + its internal parse, cmdhelp's get_spec, arg_error/synopsis), so 4 resolves x 3 subcommands = the reported 12. tcl::prefix was the ONLY affected ensemble: all tclcore ensemble docs pass unqualified names, but the single-component ones (info/dict/file/ namespace/array/encoding/zipfs) derive an empty qualifier which was already mapped to ::. Both fixes: - tclcore call site now passes ::tcl::prefix. - ensemble_subcommands_definition normalizes its ensemble argument to fully-qualified in the CALLER's context (uplevel namespace which, :: prepend fallback) before deriving anything - covering any future relative multi-component caller. Verified: zero warnings at both depths; rendered help byte-identical (6301/5585 chars); generator snippet identical for qualified vs unqualified input. New pin ensembledef.test ensembledef_unqualified_ensemble_name_no_warnings (fixture two-component ensemble called relatively under stderr capture; capture_stderr helper added to the file). src/tests/modules/AGENTS.md index updated (ensembledef.test now listed). G-175 drafted (proposed): goals/G-175-punkargs-dynamic-resolve-multiplicity.md - the warning was the only signal of the 4x-per-render @dynamic resolve multiplicity; the goal records the verdict question (render-scoped single resolution vs pinned accept), the attributed resolve sites, the measured cost floor (redundant builder calls ~3ms on 'i ::tcl::prefix', ~22ms on 'i ::dict' steady-state; the full argdata re-processing share is unmeasured - first investigation step), and candidate mechanisms smallest-first. GOALS.md indexed. punk::args 0.25.1 -> 0.25.2, punk::args::moduledoc::tclcore 0.4.1 -> 0.4.2, project 0.62.1 -> 0.62.2 + CHANGELOG (user-visible repl stderr noise fix). Suites: testbody_lint 1688 clean; goals_lint clean (79 active / 96 archived); modules tree 1335 total / 1324 pass / 11 constraint-skipped / 0 fail (zig-built tclsh90s 9.0.5); make.tcl projectversion consistency + staleness OK. Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
661418b732 |
punk::ansi 0.2.1 + punk::args 0.25.1: add missing -- to 'regexp -about' sites - dash-led grepstr patterns and -type regexp values work again (project 0.62.1)
grepstr regression report (user, 2026-08-08): 'grepstr -h underline
-group test-group' errored 'bad option "-group": must be -all, -about,
-indices, ...' - regexp's own option list - with or without the --
end-of-options marker, where an old punk901t.exe kit worked.
Diagnosis: the punk::args parse layer was never at fault. A live probe
seats the dash-led word as the pattern value in both invocation forms
(without a marker via the starved-values/valmin reservation rule). The
failure was the body's capture-group probe 'regexp -about $pattern' in
punk::ansi::grepstr - no -- guard, so any dash-led PATTERN VALUE was
read as a regexp option. Present since the proc's introduction
(
|
2 days ago |
|
|
df74c3b2db |
punk::args 0.25.0: bounded -multiple ranges participate in leader/value allocation (directed work post-G-053; project 0.62.0)
Bounded -multiple occurrence ranges now PARTICIPATE in positional allocation
for leaders and values instead of being post-loop enforcement only.
Previously greedy collection overran a bounded max unless a type screen
happened to stop it - untyped {3 3} followed by a -multiple tail collected 4
words and occurrencecount then reported the overrun the allocation itself
created (and typed {3 3} with four consecutive ints failed identically) -
and a later REQUIRED ranged argument was starved to a single reserved
clause.
Three cooperating sites:
(a) get_dict_can_assign_value caps a satisfied -multiple argument at its
bounded max: the word is yielded (no-consume) so the caller's retreat
advances to the next argument - one proc serving both the leaders and
values loops. The yield carries a G-082 rejection record of new kind
'occurrence', and both loops' overflow selection sites render it as the
pointed occurrence-limit report with the G-053 occurrencecount errorcode
(count = the attempted occurrence) instead of the generic toomanyarguments,
so genuine over-supply keeps its pointed class - now describing an overflow
the allocator refused rather than one it created.
(b) Reservations are min-occurrence aware: the allocator's tail_needs and
the derived valmin floor (leader/value split + option-scan reservation)
reserve min-occurrences x min-clause-length for a required ranged argument
- a following required -multiple {3 3} reserves 3 clauses, {2 2} pair
clauses reserve 4 words - so earlier greed cannot starve it. An explicit
'@values -min' still overrides the derived floor; legacy boolean -multiple
(no MULTIPLE_RANGES entry) reserves exactly as before.
(c) The greedy leader scan caps a bounded -multiple last leader at max
occurrences (via the leader_posn_names_assigned counter), so remaining
words flow to the opts/values sections. (The split is a separate pre-loop
scan - capping only the loops left over-provided leader words raising
toomanyarguments.)
First occurrences are never capped (resolve guarantees range max >= 1);
{0 1} at-most-once scalars are unaffected (no collection); bounded-variable
ranges take greedy-up-to-max deterministically; legacy boolean greed is
byte-unchanged (pinned). define -help -multiple documents the allocation
semantics.
multipleranges.test gains 7 allocation pins: untyped/typed {3 3} cap incl
the cap-beats-type-screen four-ints case, greedy-up-to-max {1 2},
required-range and pair-clause reservations, the leaders-side scan cap +
split floor, the pointed over-supply report, and a legacy-greed-unchanged
guard. src/tests/modules/AGENTS.md index updated.
Project 0.61.0 -> 0.62.0 + CHANGELOG (allocation behaviour is user-visible
shell parsing). punk::args 0.24.0 -> 0.25.0.
Suites: punk/args 408/0; modules tree 1320 pass / 11 constraint-skipped /
0 fail (zig-built tclsh90s 9.0.5); testbody_lint clean; make.tcl
projectversion consistency OK.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 days ago |
|
|
39e0ec2ba7 |
G-084 achieved: settled cross-member -multiple rejection + value-parsekey integrity + storage-key attribution (punk::args 0.24.0, project 0.61.0)
G-084 increment 2 + achieved flip - parsekey completeness closed: Cross-member -multiple on a shared-parsekey option group is now a DEFINE-TIME error unless ALL members belong to one @opts group marked -parsekeymode error (G-083 mutual exclusivity makes per-member collection well-defined; a single -multiple member with its own parsekey is unrestricted). This settles the G-084 cross-member accumulation decision as rejection rather than accumulate-in-received-order: collection on one storage key is ambiguous (collect-vs-replace undefined), and rejection eliminates the silent loss without new collection semantics. The check runs AFTER the G-053 canonicalisation so range forms verdict correctly ({0 1} replace-shape allowed; a pre-canonicalisation placement would raise a raw non-boolean error for any range form). Value -parsekey integrity settled at define time: duplicate value parsekeys rejected (trailing values consume positionally - the shared slot silently overwrote), dash-led value parsekeys rejected (they landed in the options namespace of result/received and aborted parse with an internal error in the option-shaped validation paths; every option storage key is dash-led, so this one rule also removes all cross-class collisions). parse_status/parse_report storage-key attribution: parse_status_build now resolves a storage key claimed by exactly ONE argument (value -parsekey, declared option -parsekey, '='-suffixed optset tail) back to that argument, so argstatus/Source report received with the value-in-effect instead of default/0. Shared-parsekey groups stay unresolved - the remaining recorded display gap (engine-level per-member tracking; archived as the goal's open Follow-on). undefine/undefine_deflist now return "" (previously the whole internal cache dict to any caller capturing the value). define -help documents -parsekey for the first time (rename semantics for options and values, leader rejection, shared groups and -parsekeymode, last-defined-member defaults precedence, the -multiple rule, value-key uniqueness/non-dash). Moduledoc tclcore comment corrected (leader -parsekey settled as rejection, not pending). Internal sweep: dead values-loop identifiers removed (val_ident/val_ident_is_parsekey/values-side seen_pks), leader reverse map removed (VAL_NAMES-driven build), dead parsekey-from--default derivation removed, stale pre-G-084 comments corrected. Tests: parsekey_shared_key_multiple_rejected strengthened (message pins, {0 1}/{0 4} range coverage, the -parsekeymode error escape hatch incl collection and optionconflict); new parsekey_value_parsekey_integrity, parsereport_storagekey_attribution, parsestatus_storagekey_attribution; inc-1 comment damage repaired (duplicated block, eaten G-083 provenance lines, stale GAP-era comment); 2026-08-08 future-dating normalized to 2026-08-07 in touched files (CHANGELOG 0.59.0/0.60.0 headers corrected likewise; the underlying commits landed 2026-08-07 AEST). Goal flip (user-approved): the Goal line's accumulate wording amended to the settled define-time-rejection design; G-084 flipped achieved 2026-08-07 and archived (detail -> goals/archive/, index -> GOALS-archive.md, reference sweep applied - G-167 survey note gains achieved markers for G-053/G-083/G-084; Follow-on recorded: shared-group per-member received attribution => open). Detail file gains ## Progress (inc 1 + inc 2 + flip evidence). src/tests/modules/AGENTS.md punk/args index updated to the settled-pin state. Project 0.60.0 -> 0.61.0 + CHANGELOG (value -parsekey support and the define-time integrity rules are user-visible shell behaviour; G-053 precedent). punk::args 0.23.0 -> 0.24.0. Suites: punk/args 401/0; modules tree 1313 pass / 11 constraint-skipped / 0 fail (zig-built tclsh90s 9.0.5); testbody_lint clean; goals_lint clean; punkboot version-parsing 81/81; make.tcl projectversion consistency OK. Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
5037a9b51d |
.test authoring guard-rails: testbody_lint.tcl, runtests empty-actual hint, sanction 'return $result'; fix vacuous args.test test
- scriptlib/developer/testbody_lint.tcl (new): tcltest .test lint per
src/tests/AGENTS.md Verification. E-level: a -body whose final command
always returns empty vs a -result that cannot match empty under its
-match mode; test invocations with no -body at all (vacuous pass);
unbalanced-brace parse kills. W-level: uninterpretable shapes.
Hand-rolled command-word splitter (the corpus '{desc}\' style is
command-legal but list-illegal), namespace-eval recursion, literal
{*}{...} splices, -selftest (8 fixtures) + -stats. 142 files /
1674 tests parse clean.
- src/tests/runtests.tcl: FAILED reports with an empty actual and a
non-empty expected append a hint= (compact) / hint : (markdown) line
naming the trailing 'set result'/'return $result' convention, so the
failure carries its own diagnosis. JSON reports unchanged.
- src/tests/modules/punk/args/testsuites/args/args.test: the
literalprefix sibling of parse_withdef_value_leading_multiple_not_greedy
was passing VACUOUSLY - a missing description made the braced
description word swallow -setup/-body/-cleanup/-result, so tcltest ran
an empty body against the default -result "". Description restored,
orphan closing brace removed; the de-vacuized test executes and passes
(file 34/34).
- AGENTS.md (root), src/tests/AGENTS.md, .agents/.claude tcl-runtests
SKILL.md (byte-identical copies): the body-ender convention now
sanctions 'return $result' alongside 'set result' (verified on 8.6 and
9.0: default -returnCodes {ok return} accepts the return form,
-cleanup still runs, an explicit -returnCodes list omitting 'return'
rejects it loudly); linter and hint documented.
Verification: testbody_lint -selftest PASS on tclsh90s and tclsh86ts;
corpus lint clean; args.test 34/34; full suite in both runner modes with
runtests_parity.tcl PARITY: ok (1677 tests, 1631 pass). Residual 23
failures are pre-existing/environment, not this change: 12 maketclhelp
(auto_execok tclsh Bash-env trap; pass under PowerShell), 8
maketcllibfetch + 2 maketclbakelist (reproduce identically with this
runtests.tcl change stashed), core exec-14.3 (pins the pre-'-encoding'
exec error message vs tcl 9.0.5).
Claude-Session: https://claude.ai/code/session_016Bk571eG3prsJWYnewboW2
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
|
2 days ago |
|
|
abd8616f3c |
G-084 inc 1: value -parsekey support + leader -parsekey define-time rejection + defaults precedence
G-084 (punk::args 0.23.0) increment 1 - parsekey completeness part 1:
Value -parsekey is now supported (was: accepted at define time but aborted
parse). A value record declaring -parsekey renames its result `values` slot
and its `received` key to the parsekey (e.g `@values {v1 -parsekey renamed
-type string}` parses `hello` to `values={renamed hello}`, `received` keyed
by `renamed`), and -multiple value members collect under the parsekey (the
`variable` setvalues form `?name value...?` pairs collect under `name_value`
- the motivating caller that carried the `#todo - fix -parsekey for leaders
and values` moduledoc comment).
Implementation: VAL_DEFAULTS and the values_dict init/storage are keyed by
parsekey (matching the already-parsekey-keyed VAL_REQUIRED); a new
api_valnames_received list tracks the parsekey (the internal valnames_received
stays argname-keyed for the -multiple first/continuation gate and G-053
occurrence enforcement); api_valnames_received drives the
required-satisfaction check and the received dict; a per-form
val_pk2name/leader_pk2name reverse map lets the valmin clause-length fallback
and the post-parse validation loop resolve a parsekey back to its argname
for ARG_INFO/arg_checks lookups.
-parsekey on a leader is now REJECTED at define time with a clear message
(was: silently ignored) - no live caller uses a leader -parsekey, so the
goal's no-silent-ignore contract is met by rejection rather than parallel
hot-path surgery; the dead req_name derivation in the leaders resolve branch
is removed. The @values directive line still rejects -parsekey (a
group-default parsekey is not a feature; per-arg value -parsekey is).
The defaulted-members precedence rule for a shared-parsekey group (none
received) is now documented as last-defined-member-wins (deterministic in
definition order) and the in-code `? review` is removed.
parsekey.test: the value GAP flipped to parsekey_value_result_key_settled,
the leader GAP flipped to parsekey_leader_parsekey_rejected, the @values-line
GAP split to parsekey_values_line_rejects_parsekey; the defaults GAP flipped
to a settled pin (parsekey_shared_key_member_defaults).
dev/parsekey-knownbugs.test: the value and leader disabled pins retired
(settled in parsekey.test); the cross-member -multiple accumulation pin
remains (increment 3, pending the design decision).
Full punk/args suite 399/0 (1 skipped), punk/ns 125/125, broader punk sweep
989/0. Cross-member -multiple collection (inc 3) and the parse_report/
parse_status received-attribution display gap (inc 2) remain.
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
|
2 days ago |
|
|
c1f64ca0ab |
G-174 drafted (proposed): cmd_traverse word accounting - the doc-lookup walk never drops argument words
Root-caused from 'i a? web green' presenting the loose sample form (ordinal 5) instead of web (ordinal 3): punk::args form narrowing is sound (parse_status on the full tail reports the web/sample ambiguity correctly); punk::ns::cmd_traverse drops all but the last trailing word for commands whose definition's first form is zero-arg (a?'s sgr_overview) - the dropped words land in neither args_resolved nor args_remaining, so cmdhelp's advisory parse narrows on a one-word tail and cleanly selects the wrong form with no failure signal. The goal records the probe evidence, the four-step drop mechanism (first-form-only inspection, ensemble-shape test, the '#todo - return?' empty-leader break, the code-10 last-snapshot fallthrough), the consumer sensitivity split (docid-only vs args_remaining-sensitive), and the coverage determination: cmdflow/cmdhelp pin the choice-walk parity and post-resolution narrowing arcs, but nothing asserts the conservation invariant, no fixture has the zero-arg-first-form shape, and the code-7/code-10 lanes are unwitnessed. Approach: characterise first (defect witnesses pinned, flipped by the fix commit), minimal fix at the annotated sites, consumer verification, with first-form-only inspection and the ansi-side sample-form tightening held as recorded decision items. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
2aad4d1777 |
G-053 achieved: punk::args range-valued -multiple occurrence arity (punk::args 0.22.0, project 0.60.0)
-multiple now accepts a {min max} range (max -1 = unbounded) alongside the
legacy booleans 0/1, so a definition can declare at most once ({0 1}, a second
occurrence is a parse error), bounded repetition ({2 4}), or one-or-more
({1 -1}) instead of choosing between silent last-wins (0) and unbounded
collection (1).
The spec compiler canonicalises once at resolve: the stored -multiple becomes
the computed boolean (list-shape collect: true for max>1 or -1, false for
legacy 0 and max==1) so every existing collect-vs-replace / scalar-vs-list /
leader-value-single-multiple hot-path truth-test stays correct, and the range
companions (min/max/maxbounded) live in a separate per-form MULTIPLE_RANGES
dict - NOT in ARG_INFO, so they do not ride along when ARG_INFO is round-tripped
as a spec via resolved_def copyfrom. Legacy 0/1 and boolean strings
(true/false/yes/no) are coerced to the boolean and stay byte-unchanged (no
MULTIPLE_RANGES entry for unlimited cases, so {0 -1} is equivalent to legacy 1).
Resolve validation: max positive or -1, min <= max, and the -optional/range-min
reconciliation (non-zero min forces presence, contradicts -optional -> reject
with a clear message; declare -optional 0). The value-shape rule: max==1 forms
stay scalar, max>1 or -1 yield the occurrence list.
Parse enforcement: a new PUNKARGS VALIDATION occurrencecount failure class
(payload <argname> count <n> min <m> | max <m>) fires in a single post-loop pass
per section (opts/leaders/values) via a private::multiple_range_enforce
helper. Over-max is a hard contradiction (fires in both normal and
viability-probe modes; parse_status_classify maps it to invalid); under-min is
pure end-of-input exhaustion (SUPPRESSED in the G-152 viability probe via the
viabilitycheck arg, classified incomplete so a viable form reports incomplete
not invalid). Legacy -multiple 1 required with 0 occurrences still reports
trailingvaluecount (byte-unchanged, not occurrencecount).
Rendering: the usage-table Multi column reflects the range (0-1 / 2-4 / 1+ for
unbounded-with-floor; the greencheck stays for legacy 1), the string renderer
emits MULTI:0-1 etc., and the synopsis distinguishes at-most-once (?arg?, no
ellipsis) from repeating (arg...). -multipleunique/-multipleuniqueset compose
with max>1 ranges unchanged. define -help documents the range form and the
-optional/range-min rule.
New testsuite multipleranges.test (28 tests: 13 define-time
canonicalisation+validation, 12 parse-time enforcement incl parse_status
verdicts and a legacy-required-still-trailingvaluecount guard, 3 rendering).
Legacy untouched by default confirmed: full punk/args suite 399/0 (3 skipped),
punk/ns 125/125. All G-053 acceptance criteria met; goal flipped to achieved
2026-08-08 and archived (detail -> goals/archive/, index -> GOALS-archive.md,
reference sweep applied to G-072/G-084, deferred G-084 cross-member -multiple
collection decision recorded as a Follow-on => goal G-084).
Project version 0.59.0 -> 0.60.0 (minor: backward-compatible behaviour
addition). punk::args module 0.21.0 -> 0.22.0.
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
|
2 days ago |
|
|
35008f7338 |
G-084 notes: record the shared-parsekey received-attribution display gap
parse_report's Source column and parse_status's per-arg `received` count both
report default/0 for an explicitly-supplied shared-parsekey member (e.g
parse_report {-exact ...} withid ::lsearch shows every MATCHSTYLE member as
(default) though the value is correctly bridged) - parse_status_build keys
the positions dict by the storage key, so no per-member received attribution
survives the fold. Pre-existing (G-151 bridge, G-049 attribution loop), not
introduced by G-083. Flip when the engine-level storage-key model G-084 owns
lands (the same follow-on that retires the value-bridge).
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
|
2 days ago |
|
|
9125d56237 |
G-083 increment 3 achieved: punk::args argument-relations usage rendering + lsearch moduledoc adoption (punk::args 0.21.0, project 0.59.0)
The -conflicts and -parsekeymode error vocabulary (inc 1, 0.19.0) and its parse-time optionconflict enforcement (inc 2, 0.20.0) now surface in usage/arg_error and synopsis output, and the lsearch tclcore moduledoc models its documented option incompatibilities with the new vocabulary. Rendering: - A per-arg -conflicts list appends a "conflicts with: <targets>" hint to the argument's help text in the usage table (targets resolved to display names via lookup_optset, so a parsekey target shows its member flag, not the raw parsekey). - A named @opts group marked -parsekeymode error is annotated "mutually exclusive (distinct members may not be combined)" in its group header; override (default) groups carry no such annotation. - The synopsis one-line form carries no conflict detail. lsearch moduledoc (tclcore): - -sorted gains -conflicts {-glob -regexp} and -bisect gains -conflicts {-all -not} (per-arg conflicts; the whole group stays -parsekeymode override so -glob/-regexp remain last-wins). - The "(documentation incomplete - punk::args fixes required for grouped mutually exclusive options and prefix calculation)" caveat is dropped from the @cmd -help. clock clicks left unchanged - its active positional-choice definition already models exclusivity (exactly-one-of) and the acceptance clause names lsearch only. relations.test extended with 8 increment-3 pins: 4 rendering (conflicts_usage_hint, parsekeymode_error_usage_group_header, parsekeymode_override_no_header_annotation, conflicts_synopsis_no_hint) and 4 lsearch adoption (lsearch_sorted_conflicts_glob + lsearch_bisect_conflicts_all raise optionconflict via errorcode substring match, lsearch_glob_regexp_last_wins stays last-wins, lsearch_caveat_dropped). Legacy untouched by default (no -conflicts/parsekeymode-error definition carries no new rendering). Full punk/args suite 371/0 (3 skipped); tclcoreparity 10/10; punk/ns 125/125. All G-083 acceptance criteria met; goal flipped to achieved 2026-08-08 and archived (detail -> goals/archive/, index -> GOALS-archive.md, reference sweep applied to G-053/G-084, deferred -requires/-implies dependency relations recorded as an open Follow-on). Project version 0.58.0 -> 0.59.0 (minor: backward-compatible behaviour additions, following the G-173 punk::path precedent). punk::args module 0.20.0 -> 0.21.0. Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co |
2 days ago |
|
|
43f009ed80 |
G-083 increment 2: punk::args optionconflict parse-time enforcement (0.20.0)
The -conflicts and -parsekeymode error vocabulary declared at define time
(0.19.0) is now enforced at parse. A new optionconflict failure class joins the
PUNKARGS VALIDATION errorcode vocabulary, mirroring optionmissing's shape:
{optionconflict <arg_a> <arg_b> received <receivednames>} - it names both
offending received arguments, for both per-arg -conflicts violations (any
pair, cross-group) and -parsekeymode error group co-occurrence (distinct
members of a shared-parsekey group).
The check runs in a single post-resolution site in get_dict_form (after the
optionmissing/valuemissing block), so the ordinary option path and the mash
(short-flag bundling) path share it - both raise identically. Checked against
RECEIVED arguments only (defaults never conflict), after prefix/abbreviation
resolution, on optset identity (a new optsets_received tracker for options,
since flagsreceived collapses shared-parsekey members onto one api_opt). Runs
unconditionally - a received conflict is a hard contradiction in any mode, not
end-of-input exhaustion, so parse_status_classify maps optionconflict to invalid
(not incomplete) and the candidacy/viability probe reports it.
Define-time check added: a group marked -parsekeymode error must also declare a
non-empty -parsekey (the strict mode only applies to a shared-parsekey group).
relations.test extended with 7 enforcement pins (raise cases for -conflicts
and -parsekeymode error, defaults-never-conflict, cross-group conflicts,
one-received-ok, override-legacy last-wins, parse_status invalid). buildversion
0.19.0 -> 0.20.0.
Bug found and fixed during the increment: the group-co-occurrence dedup check
initially used `ni` (not-in) where `in` was meant - `ni` returns true on an
empty list, so it skipped every member and the check never fired. Corrected
to `in`.
Legacy untouched by default: -parsekeymode override is the default and absent
-conflicts means no check runs, so the full existing suite (including the
pinned parsekey_repeat_ordering last-wins / prepend-defaults idiom) passes
unchanged.
Verification: full punk/args suite via canonical tclsh90s - 363 total / 360
passed / 3 skipped (punkargsKnownBug) / 0 failed; punk/ns suite 125/125 clean.
goals_lint clean. No punkproject.toml bump (module API addition, not shell-
level user-visible behaviour yet - the lsearch moduledoc adoption that ships
user-visible behaviour lands in increment 3).
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
|
2 days ago |
|
|
055f4bbf2f |
G-083 increment 1: punk::args argument-relations define-time vocabulary (0.19.0)
Spec compiler (resolve) accepts and stores the new relation keys: - per-argument -conflicts <list>: parsekeys or flag names that must not be RECEIVED together with this argument; checked against received args only at parse time (defaults never conflict) - parse-time optionconflict enforcement lands in a later G-083 increment. - @opts-level -parsekeymode override|error: per named OPT_GROUPS group; error = distinct-member co-occurrence within a shared-parsekey group raises optionconflict at parse; override = legacy last-wins, the default. Both keys are cross-validated at resolve: -conflicts targets must name a defined argname or declared -parsekey; -parsekeymode requires -group and a value of override|error. Define-time integrity hole closed: a -parsekey colliding with a distinct defined argument's name (one not sharing that -parsekey) is now a resolve error instead of silently forming an implicit shared-key group (parsekey_collides_with_defined_optname_GAP flipped in parsekey.test to a define-time error pin, plus redundant-self-name and deliberate-shared-group guards). Design settled (recorded in the goal detail): -parsekeymode is per named group (OPT_GROUPS entry, keyed by the @opts line's -group), not form-wide. Rationale: lsearch uses per-arg -conflicts only (partial conflicts, groups stay default override); clock clicks uses -parsekeymode error on its single named group (full pairwise exclusivity). Unnamed shared-parsekey groups default override. Legacy untouched by default: -parsekeymode override is the default and absent -conflicts means no check runs; the pinned parsekey_repeat_ordering last-wins / prepend-defaults idiom and the full existing suite pass unchanged. New testsuite relations.test pins the define-time vocabulary (7 tests, matching the longopts.test/mashopts.test error-pin style). buildversion 0.18.0 -> 0.19.0. Verification: full punk/args suite via canonical tclsh90s - 356 total / 353 passed / 3 skipped (punkargsKnownBug) / 0 failed. goals_lint clean. No punkproject.toml bump (define-time only; no shell-level user-visible behaviour yet - the module change, not the shell product). Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co |
2 days ago |
|
|
6b4aeac95f |
punk::args: characterise longopt style distinctions + mash edges (new longopts.test)
Gap-fill from a coverage review of long-option and mashopt parsing: the module's comment blocks specify style distinctions the suite never pinned. All behaviour was live-probed before pinning (characterisation, not aspiration). New testsuites/args/longopts.test (6 tests): - mixed optset -f|--file|--file= accepts inline/spaced/short-alias forms incl unique-prefix abbreviation of the longopt itself (--fi=abc / --fi abc) - gnu-only --flag= splits at the first = only (--filename=a=b -> a=b), accepts an empty inline value, rejects spaced and solo usage (badoptionformat) - plain --flag accepts spaced only; inline =value is invalidoption - the two =-member resolve-time definition errors (-type none with an = member; optional ?type? member without one) surface at first parse - single-dash -flag=value is never split at the = (invalidoption) - @opts -any 1 adhoc lane: undefined --flag=value splits to --flag + value, but single-dash -zz=5 stays a WHOLE adhoc flagname expecting a following value mashopts.test additions (2 tests): a mash containing an undefined letter is rejected whole (invalidoption naming the mashable set); under -any 1 -mash 1 defined flags still mash while undefined mash-lookalike tokens (-xy, -az) are adhoc flags taking the next word as value - never mash attempts. Error-shape pins use the first three -errorcode elements (PUNKARGS VALIDATION + failclass) rather than the ANSI-rendered messages; the two resolve errors are pinned by distinctive message substrings (plain text, no ANSI). Verified: runtests -include-paths modules/punk/args/testsuites/args longopts.test mashopts.test via tclsh90s - 13/13 pass, no warnings. src/tests/modules/AGENTS.md punk/args index entry updated (DOX pass). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com |
2 days ago |
|
|
f48bf78900 |
G-083: activate (proposed -> active) - punk::args argument relations
Activation-freshness overlap survey (goals_xref score G-083) confirmed the existing Notes already record the real relationships (G-053, G-072, G-084 - all linked). G-167's back-pointer explicitly declares a deliberate non-overlap with no sequencing constraint; remaining unlinked pairs are low-score term-only siblings with no path overlap. No new Related: lines warranted. This work is a prerequisite for G-084 (parsekey completeness), whose cross-member -multiple combination decision should be made with this goal's relations vocabulary in hand. G-053 (occurrence arity) is slotted before G-084 in the same sequence at the user's direction. Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=unknown |
2 days ago |
|
|
3450a9d3cb |
Refresh stale punkbin commit-hash pins in archived goals (punkbin shellspy->punkshell sweep)
The punkbin artifact repo carried the wrong project token ("shellspy" - the
experimental subcommand, not the project name per root AGENTS.md) in 10 commit
messages (subjects AND bodies) back to the repo's earliest scaffolding. A
message-only `git filter-branch --msg-filter 'sed s/shellspy/punkshell/g'` over
the whole shellspy-bearing history rewrote all 10 (20 commits replayed, trees
byte-identical - --msg-filter cannot alter content), force-pushed to
origin/master (now 63f5e558). punkbin is git-only (no fossil).
The rewrite changed every commit hash in the swept range, so punkbin commit-hash
pins in archived goal detail files went stale. Refreshed all of them to the new
hashes so the records stay honest pointers rather than dangling references:
- G-172 (3 pins): ab5611d -> a73d862e; 59e7475 -> 63f5e558 (this goal's two
in-situ republish commits - my session's defect; the earlier 2-commit amend
had already left these pins stale and this refresh clears them).
- G-128 (3 pins): 1b471fc -> 2d2bf48 (punkres stamper publication).
- G-139 (1 pin): ee571ed -> e5c86eb (lib tier r1 publication).
- G-123 (2 pins): 1f10390 -> 0d49aa7 (retroactive schema-v2 sidecars).
- G-165 (1 pin): a22e16b -> a8303c4 (punkzip root-strip/exclude build options).
Per goals/AGENTS.md archived files are frozen except Follow-on dispositions;
this refresh is a sanctioned exception under explicit user permission to make
archived goals honest regarding hashes. Pure hash-token substitutions - no
prose, Scope, Goal or Acceptance text changed. The dated achievement-time
qualifiers around the pins (e.g "LOCAL ONLY - not pushed", "STAGED", "REMAINS
for acceptance") are point-in-time history and stay untouched. goals_lint clean.
Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co
|
2 days ago |
|
|
2954d08f84 |
G-172 achieved: flip to achieved + archive (distributed-binary CPU floor)
Rebuild + in-situ republish (Approach 6) completed the acceptance. Full `zig build bootstrap` (pinned 0.16.0) rebuilt the r2 family WITH the G-172 cpu_floor field now in the embedded [provenance] record (re-stage picked up the build905.zig floor-field edit; zig-cached C compiles, only the wrap + emit re-ran). family_check passed for all three members (the new embed_cpu_floor/embed_cpu_model assertions green). Audit of the rebuilt r2 exes: all three PASS at the baseline floor (zmm=0 ymm=0 out-of-floor=0). Published in-situ to punkbin (git 59e7475, pushed origin/master): the three r2 exes + three r2 tomls replaced under existing names/revisions; each toml [provenance] now carries cpu_floor="baseline" + cpu_model="x86_64"; the [tests] tclcore line refreshed to the shipped-codegen gate evidence (passed=56041 failed=8, the Aug-06 baseline-rebuild test-gate - was 56039/9); library [tests] lines unchanged; sha1sums.txt: the 6 r2 lines updated. build_id unchanged per artifact (the floor field does not enter the identity digest); sha1/size/built updated. Every acceptance conjunct verified on this Zen 5 / v4 host: audit zmm=0 on the republished artifacts; -Dcpu=native still host-tuned (probe: native zmm=123 FAIL at baseline, PASS at v4 - the floor is a default, not a restriction); the republished tomls state the floor; punk-runtime surfaces it (info/list/use/fetch); use/run produce a named 0xC000001D diagnosis on a below-floor recorded cpu_model (verified by mocked-host tests - not end-to-end demonstrable here: every published artifact is baseline/v1 which every host meets, and no x86-64 level exceeds v4); fetch stays ungated. DOX closeout: detail file -> goals/archive/ (pure rename; Status achieved 2026-08-07; verification evidence + ## Follow-ons recorded). Index entry -> GOALS-archive.md (removed from GOALS.md). Reference sweep: only the GOALS.md index entry mentioned G-172 in the live tier (no pending-tense rewrites); design- decision Notes pointers added to G-105 (inherits the settled default_target cpu_model shape) and G-130 (consumes the baseline floor decision on its i686 axis). goals_lint clean (80 active, 93 archived); goals_followons parses the 2 open Follow-ons (r1-generation disposition; bin/ punk9* kit rebake). Assisted-by: harness=pi; primary-model=huggingface/zai-org/GLM-5.2; api-location=huggingface.co |
3 days ago |