The layout custom/_project bootsupport sync picks up files newly arrived in
src/bootsupport on the following run (same two-pass propagation as the guarded
prune tooling); punk.project-0.1 and punk.shell-0.1 copies now carry the
stage-2 handler/modpod versions with the superseded copies pruned.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport refresh following the stage-2 cutover; superseded 0.1.1
handler and 0.1.4 modpod pruned (the modpod copy required manual deletion -
the running make.tcl mounts it and the prune self-locks; flagged in the G-087
detail file). Layout custom/_project bootsupport copies mirrored by the build.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::cap::handlers::templates 0.2.0: layout refs are fauxlink files
(<alias>#<encodedtarget>.fauxlink|.fxlnk, target relative to
<projectroot>/src/project_layouts, resolved via the fauxlink module).
get_itemdict_projectlayoutrefs selects *#*.fauxlink/.fxlnk with fauxlink-derived
names; get_itemdict_projectlayouts derives the layout folder from the resolved
targetpath; the <alias>@<target>.ref parser is removed and .ref files are no
longer recognised. Alias-less (leading-#) refs and unresolvable refs are
skipped with a warning - punkcheck-based tooling excludes leading-# filenames,
so layout refs must carry a non-empty nominal name. Also fixes the ignore*
skip, which previously matched against the full glob path and never applied.
All 7 live-tier refs renamed via a fauxlink::link_as-driven migration script
(each generated name round-trip-verified through fauxlink::resolve before
rename): decktemplates vendor/punk x4 (alias-less refs gained their target-tail
aliases: basic, minimal, sample-0.1), custom/_project x2, and the
module-shipped modpod ref (punk::mix::templates 0.1.5). Zero-byte property and
all visible layout names unchanged. src/project_layouts/README.md ref-grammar
section rewritten for fauxlink.
Note: git's rename pairing crosses two of the zero-byte vendor/punk refs
(sample-0.1 <-> project) - content-identical empty files; the true mapping is
alias-preserving as described above.
Verified: stage-2 scratch checks 7/7 (name parity incl exact punk.project,
decoy alias-less ref warned+skipped, old-grammar decoy ignored); runtests
prune/fossilmove/multishell/libsearch pass; end-to-end dev project.new
materializes a full project from the default punk.project layout.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport: fauxlink 0.1.2 -> 0.2.0 in src/bootsupport and the
custom/_project layout copies; superseded 0.1.2 pruned, along with the layout
copies' templates-0.1.3.tm prunes deferred by the earlier transient lock.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
make.tcl bootsupport batched build-output refresh (punkcheck-managed): fauxlink
0.1.1 -> 0.1.2, plus catch-up of source versions that had moved since the last
refresh - punk::ansi 0.1.3, punk::args 0.12.3, punk::lib 0.5.0, punk::ns 0.8.0,
punk::repl 0.5.2, tomlish 1.1.10 -> 1.1.12, test/tomlish-1.1.5 modpod, and this
morning's G-087 hygiene bumps (cap handlers templates 0.1.1, punk::mix::base
0.1.1, commandset layout/module/scriptwrap 0.1.1, commandset project 0.2.2,
punk::mix templates 0.1.4). Superseded versions pruned; the same refresh is
mirrored into the custom/_project layout bootsupport copies by the build.
templates-0.1.3.tm prune initially failed with a transient file lock and was
removed manually after verification.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- punk::mix::templates modpod (0.1.4): dead templates/layouts/project payload
subtree removed - design-generation residue with no reader; layout payloads
live in src/project_layouts, located via layout_refs.
- src/make.tcl: unused old_layout_update_list (referencing the long-gone
src/mixtemplates and modules/punk/mix/templates paths) removed; bootsupport
help text now names src/project_layouts/custom/_project/<layoutname> instead
of mixtemplates.
- src/project_layouts custom/_project make.tcl copies: punkcheck-managed sync
outputs refreshed by the verification 'make.tcl modules' run.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
- @vendor+punk+project-0.1.ref renamed to project@vendor+punk+project-0.1.ref:
the alias yields the exact layout name 'punk.project', so project.new's
defaulted -layout resolves unambiguously (previously tcl::prefix::match saw
only punk.project-0.1 / punk.project-0.1_overrides).
- Junk/test refs removed from the selectable layout list: test2, the
custom/_project duplicate sample-0.1 ref, and the alias-less punk.shell-0.1
ref whose target was an a.txt-only folder (folder removed too; the real
shell layout remains exposed as punk.shell-0.1_overrides).
- src/project_layouts/README.md rewritten to describe the implemented
punk.templates + layout_refs mechanism including the ref filename grammar,
the not-yet-implemented overlay semantics, and a G-087 pointer; the dead
punk.projectlayout capability description is gone.
Layout names after this change: punk.sample-0.1 punk.project punk.minimal
punk.basic punk.shell-0.1_overrides punk.project-0.1_overrides.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Fixes the two user-reported symptoms of '<punkexe> src/make.tcl shell':
Missing prompts: app-punkscript correctly forces ::tcl_interactive 0 for
script execution, and punk::repl is already loaded at kit boot - so the shell
branch's 'package require punk::repl' re-loads nothing and the repl's
load-time interactivity probe (repl line ~44) never re-runs, leaving prompts
suppressed on a real console. The shell branch now recomputes
::tcl_interactive via punk::repl::is_interactive against the actual input
channel before repl::init/start. Piped behaviour unchanged (probe still
reports non-interactive).
Raw-mode 'invalid command name struct::set': the accelerator-reload block
(package forget + rename of sha1/md5/struct::* so reloads can pick up
accelerators from the restored full paths) relied on later package-require
chains to restore the forgotten packages. Under a kit, the consumers
(punk::lib, punk::du, punk::nav::fs, flagfilter) were pre-loaded at kit boot,
their requires never re-fire, and the first repl-thread-side call of a
struct::set-backed punk::lib proc (lunique_unordered's self-redefining first
invocation, reached via flagfilter/nav::fs in interactive/raw paths) hit the
destroyed command. The block now records which of the forgotten packages were
actually loaded and re-requires them immediately. Verified by thread-probe:
the repl-thread interp now shows struct::set 2.2.5 + sha1 2.0.5 restored
identically under tclsh90 and punk91 (previously absent under punk91); the
codethread was always unaffected (it re-requires its own package list).
src/AGENTS.md: new note - punk-exe-hosted make.tcl runs in a pre-loaded
interp, not a virgin one (no-op requires, load-time state like the
tcl_interactive probe, kit-vs-bootsupport module provenance mixing); interp
surgery in make.tcl must restore deliberately and be tested under both tclsh
and a punk exe. Layout make.tcl copies re-synced via the punkcheck channel.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Self-build guard (user-identified gap): when make.tcl is driven by a built punk
executable, the kit whose deployed executable is the running interpreter is now
skipped before any build work, with guidance to rerun under tclsh or a
different kit. Previously the pre-deploy process sweep matched processes by
executable name only and would taskkill the build's own process mid-run with
-k (suicide: remaining kits unbuilt, no recap, dangling punkcheck event);
without -k only the polite kill's refusal on console processes saved the run,
and the deploy delete of the running image would fail with a cryptic message.
The sweep additionally excludes the build's own pid unconditionally, covering
a same-named copy driving the build from a non-deploy path. Informational and
update subcommands were already safe (they exit before the kit machinery);
building other kits from a punk exe remains supported. Verified live:
'punk91 src/make.tcl vfs -confirm 0' skips punk91.exe with the warning and
processes the other kits normally; plain tclsh runs unaffected.
libunknown quietening: 'punkexe src/make.tcl <cmd>' emitted
"punk::libunknown::init already done - unnecessary call? info frame -1: ..."
because punk_main.tcl had already initialised libunknown (renaming ::package)
and make.tcl unconditionally re-sourced the bootsupport copy and called init
again, tripping init's load-bearing rename guard. make.tcl now leaves an
already-active libunknown in place (no re-source - also avoids silently
swapping the running copy for the bootsupport copy when versions diverge);
plain tclsh runs source+init exactly as before. Verified: no diagnostic from
'punk91 src/make.tcl projectversion'.
src/AGENTS.md build guidance updated (punk-exe-driven builds and the self-kit
skip); layout make.tcl copies re-synced via the punkcheck channel.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Fixes the constructed-definition indent leak user review spotted in
'make.tcl help' output (@cmd -help Description first line rendered less
indented than continuations): HELPTEXTS and the inline shell/help/toplevel
help values are now block-form (first value line whitespace-only) with a bare
@normalize in every constructed definition, per G-045's preferred style. The
braced option fragments never leaked (literal block-shaped parts get
file-style normalization) and head-form values are contractually untouched by
@normalize. Also adds a define-time capability probe (punk::args::get_spec on
representative ids inside the guarded block) so a stale punk::args that
accepts the raw text but cannot resolve a mechanism (e.g pre-@normalize
snapshots) degrades to the plain fallback immediately instead of erroring at
first parse.
AGENTS infrastructure for future documentation work: src/modules/AGENTS.md
"Documentation And Comments" gains a "punk::args definition authoring
ergonomics" subsection (G-045 mechanisms: @normalize + block form for
constructed defs, -unindentedfields, -& record continuation, container
quoting rules; plus the G-030 lessons: explicit @form -synopsis for
script-level ids, -optional 0 for pointed choiceviolation errors);
src/AGENTS.md cross-references it and names ::punkboot::argdoc as the
in-tree constructed-def exemplar. Follow-up recorded in the G-030 archive.
Verified: flush Description rendering for toplevel/subcommand/shell/help
usage; dispatch, degraded mode (PUNKBOOT_PLAIN) and usage-error paths
re-verified; layout make.tcl copies re-synced via 'make.tcl bootsupport
-confirm 0' (punkcheck channel); goals_lint unchanged (only the pre-existing
G-078/G-081 index-mirror findings).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Snapshot refresh via 'make.tcl modules -confirm 0' + 'make.tcl bootsupport
-confirm 0' after punk::args joined the bootstrap-tracked staleness set
(bootsupport had 0.5.0 vs source 0.12.0 - the new gate tripped as designed).
Superseded versions pruned by punkcheck records; project-layout bootsupport
trees and layout make.tcl copies followed via the established punkcheck
channel (punk.basic, punk.project-0.1, punk.shell-0.1).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Re-vendor the G-001 modules into bootsupport, the project-layout
bootsupport copies, and the runtime vfs: punk::repl 0.4.0 replaces 0.3.0
and opunk::console::tk 0.2.0 replaces 0.1.0.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punkcheck-managed regeneration propagating the G-049 module releases (parse-status data model, machine-parsable cmdhelp returns) into src/bootsupport/modules, the punk.project-0.1 and punk.shell-0.1 layout bootsupport copies, and _vfscommon.vfs/modules.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Output of src/make.tcl refreshing bootsupport, vfs, and project_layouts
bootsupport trees to match the recently-bumped module versions.
Assisted-by: harness=opencode; primary-model=openrouter/z-ai/glm-5.2; api-location=openrouter.ai
New 'make.tcl vfslibs' step (also run inside 'make.tcl project' before kit vfs
assembly): propagates declared vendored platform-library packages into kit vfs
lib_tcl<N> trees, ending the hand-copying that let kits ship a known-buggy
tcludp through three make invocations (the G-036/G-037 motivating case).
- declaration: src/runtime/vendorlib_vfs.toml, parsed with bootsupport tomlish
(no ad-hoc parsing; G-024's mapvfs toml conversion NOT required first - this
file is recorded as a candidate for absorption into it). [install.<name>]
entries: source (relative to src/), targets (kit vfs lib folders relative to
src/vfs/), optional supersedes (folder names removed from each target before
install - explicit, no silent mixed-version provision per G-035 concerns).
- participation is per-package per-kit; authority is the declaration - nothing
syncs undeclared, so the known vendorlib/kit twapi drift is deliberately
untouched (resolves the direction/authority design question).
- punkcheck provenance at src/vfs/.punkcheck (gitignored, outside kit
payloads); skip-if-unchanged proven (rerun: 0 copied, 9 skipped per target);
malformed/unresolvable entries fail the build naming the entry (exit 3).
- 8.6 kits upgraded (the G-036 loose-end decision, recorded): tcludp 1.0.13 is
dual-generation (pkgIndex selects tcl9udp1013.dll on 9+, udp1013t.dll on
8.5+) so the single vendorlib_tcl9 source serves punk8win.vfs/lib_tcl8;
superseded udp1.0.12 removed.
- verified on rebuilt kits: punksys/punkbi (8.6.13) and punk902z (9.0.2) all
report package require udp == 1.0.13 loading the generation-appropriate dll
from their vfs; no udp1.0.12 remains under src/vfs; punksys piped-shell exit
smoke clean.
- G-037 flipped proposed -> achieved 2026-07-08 under user direction (no
intermediate active stop).
- includes project-build byproducts via established channels: bootsupport
snapshots refreshed to punk-0.2.1 / punk::lib-0.3.0 (from today's version
bumps) and make.tcl synced into layout copies.
- project 0.4.8 (CHANGELOG entry)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
The version-mismatch and missing-header warning branches interpolated the
literal [X.Y.Z] inside double-quoted puts strings, so Tcl attempted command
substitution and the check died with `invalid command name "X.Y.Z"` the
first time a warning branch actually fired (surfaced by a manual
projectversion check during the 0.4.2 bump, whose CHANGELOG entry was
missing at the time). Brackets now backslash-escaped. Layout copies of
make.tcl synced by the project build included.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
shellfilter::run now wraps everything between tee-stack add and removal in
try/finally so the callers stdout/stderr are always restored, and the
decorative stack-status table rendering in log::critical blocks is
catch-guarded. Previously an error there aborted the run after diverting
the channels and before restoring them, leaving process stdout/stderr
broken with all subsequent output silently lost - observed when a stale
same-version textblock snapshot (old option-value syntax) called the new
punk::ansi sgr_merge_singles inside the stack-status render during tomlish
test runs.
runtests.tcl:
- testinterp tm path order: bootsupport moved to last test_tmlist element
so it wins same-version module ties over vendormodules. Rules verified
experimentally on Tcl 9.0.3 (identical under standard package unknown
and punk::libunknown): tcl:™️:add prepends each argument, head of
tcl:™️:list wins same-version ties, so the last element of a
single-call add list wins.
- testinterp auto_path gains the parent of [info library] so binary
packages such as Thread (needed by shellrun) resolve in projects
without a root lib_tcl<N>/<arch> payload.
Project version 0.2.6. Verified: full shellspy suite at baseline (517
pass / exec-14.3 known); tomlish ported suite 184/184; reconstructed
stale-module scenario now completes with captured results and live
stdout instead of silent loss.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Move vendor_source_dirty_warnings out of make.tcl into punkboot::utils as
vcs_dirty_warnings (PUNKARGS-documented, caller-label param so the
bootsupport update path can share it per G-026). make.tcl now uses a
guarded lazy require and degrades to skipped-with-warning if the
bootsupport snapshot lacks the proc - a stale/broken snapshot must never
brick the make.tcl commands used to repair it.
Chicken-and-egg-safe ordering used and now documented in
src/bootsupport/AGENTS.md ("Moving make.tcl functionality into
punkboot::utils"): edit src module + bump buildversion, make.tcl modules,
make.tcl bootsupport, only then repoint make.tcl call sites. Boot-phase
code (path setup, punkboot::lib prompts, package-availability checks)
stays self-contained in make.tcl.
Bootsupport snapshot refresh from the sanctioned pipeline: punkboot::utils
0.1.0->0.1.1, shellrun 0.1.2->0.1.4 (punk::args require fix catch-up),
punk::console 0.7.1 content catch-up; layout mirrors via the
punkcheck-tracked sync steps.
New tests: src/tests/modules/punkboot/utils/testsuites/utils/vcsdirty.test
(git fixture: dirty/clean/dedupe/label/unversioned/missing) - 25/25 across
punkboot suites; vendorupdate verified end-to-end through the module path.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Move project-version helper procs (parse_punkproject_version,
read_punkproject_version, read_changelog_latest_version) out of make.tcl
inline definitions into a loadable punkboot::utils module so the parsing
logic is unit-testable.
- src/modules/punkboot/utils-999999.0a1.0.tm: new module (0.1.0) with
the 3 procs in punkboot::utils namespace, PUNKARGS argdoc blocks.
- src/modules/punkboot/utils-buildversion.txt: initial 0.1.0.
- src/tests/modules/punkboot/utils/testsuites/utils/utils.test: 19 tests
covering section tracking, missing fields, wrong sections, whitespace,
quote styles, changelog header parsing, pre-release suffixes. All pass.
- src/make.tcl: inline procs removed; projectversion block now does
package require punkboot::utils and calls punkboot::utils:: procs.
- Layout make.tcl files (punk.shell-0.1, punk.project-0.1): same edit;
punk.basic keeps inline procs (no bootsupport tree).
- include_modules.config: added punkboot::utils entry (main + 2 layouts).
- Bootsupport snapshots propagated via make.tcl bootsupport.
- AGENTS.md: project version bump 0.2.0 -> 0.2.1 (patch: new make.tcl
projectversion subcommand is part of the product surface); added
clarifying line that make.tcl command interface warrants at least a
patch bump; src/project_layouts/ added to directories agents should
not directly modify.
- CHANGELOG.md: 0.2.1 entry.
Assisted-by: harness=opencode; primary-model=openrouter/z-ai/glm-5.2; api-location=openrouter.ai
Four project-layout template README.md files were untracked because the
layout templates' own nested .gitignore files are honoured by git as
nested ignores of the outer repo (fossil, which reads no nested ignore
files, already manages them). Two vendored critcl TODO.txt files were
swallowed by the unanchored 'todo.txt' ignore pattern matching
case-insensitively on Windows (core.ignorecase). All six force-added so
git's tracked set matches fossil's view; note force-adds protect only
these existing files - future files under the layout templates or new
vendored TODO.txt files will drop silently again unless the underlying
patterns are revisited.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
From 'tclsh src/make.tcl bootsupport' run after commit 0ee66dce -
correctly stamped and containing the final 0.3.0 content (per-console
facts + PUNKARGS @leaders restructure).
Note: the punk.shell-0.1 layout retains console-0.1.0.tm and
console-0.2.0.tm alongside the new 0.3.0 - the prune kept them (no
qualifying punkcheck install record); pending manual removal if
unwanted, per the established prune-leftovers handling.
Copies produced by the developer's src/make.tcl runs alongside the
punk::console work:
- _vfscommon.vfs: punk/console 0.1.7 -> 0.3.0 (final content),
punk/lib 0.1.6 -> 0.2.0, punk/repl 0.1.6 -> 0.2.0,
punk/tcltestrun 0.1.0 -> 0.3.0 (matching their committed source)
- bootsupport (root + punk.project/punk.shell layouts): punk/console
0.1.7 -> 0.2.0. NOTE: this snapshot was taken mid-development - it is
stamped 0.2.0 but already contains the 0.3.0 per-console facts code
(without the final PUNKARGS @leaders restructure). The next
'make.tcl bootsupport' run will supersede it with a true 0.3.0 copy.
Resolves the build-maintenance TODO: built module trees no longer accumulate
superseded intermediate versions, and .punkcheck state stays consistent because
every deletion is recorded through punkcheck's event mechanism.
punkcheck (0.3.0):
- installsource_add_virtual + installevent method targetset_addsource_virtual:
'virtual' named-value SOURCE records (-type virtual -path virtual:<id> -value <v>)
compared by stored value, participating in targetset_source_changes. Needed
because successive module versions are built from the same physical source
files - the recorded virtual module_name/module_version identify which
product of the source fileset a target is, at install and delete time.
punk::mix::cli (0.5.0):
- lib::prune_superseded_target_modules: deletes lower-version .tm siblings only
when records prove the same module line (virtual module_name match, or legacy
fallback: recorded sources share the keep-version's source folder(s) and name
prefix). Unrecorded files are never deleted - reported to stderr instead.
- lib::prune_sourcevanished_targets: mirror-prune of recorded targets whose
recorded source files no longer exist (layout bootsupport copies, vendormodule
copies) - intentional multi-version vendoring is preserved.
- build_modules_from_source_to_base prunes after each module install/skip and
records virtual module identity sources on installs.
make.tcl:
- bootsupport: non-glob include_modules.config entries track only the latest
version - superseded recorded snapshot versions pruned; project-layout copies
mirror-pruned; virtual identity recorded on snapshot installs. Calls guarded
(info commands) so a stale bootsupport snapshot degrades to a warning and the
two-pass modules+bootsupport bootstrap self-heals.
- vendormodule copies in root modules*/ mirror-pruned after install.
docs/config:
- include_modules.config headers now document the entry format (non-glob =
latest-only + prune; glob chars = keep all matches; unrecorded never pruned)
- src/AGENTS.md TODO replaced with the durable prune contract;
src/bootsupport/AGENTS.md + src/tests/modules/AGENTS.md updated
tests: src/tests/modules/punk/mix/testsuites/cli/prune.test (19 tests) covering
virtual source recording/comparison and prune identity/safety rules.
Suites: punkcheck 64/64, full suite under Tcl 9.0.3 green except pre-existing
exec-14.3.
payload sync: bootsupport snapshots, project layouts and _vfscommon.vfs pruned
of superseded intermediates (~570k lines of stale .tm copies removed).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
opunk::console (0.3.0):
- base size method resolution order: -winsize fast path -> capability gate (settled or heuristic
can_respond; unresponsive consoles get default_size with no query emission) -> pluggable
::opunk::console::size_query_provider -> default_size. The provider hook follows the
waiting-store pattern: the class carries no punk::console dependency, and non-channel
subclasses (tk widget / channel-environment terminals) simply override size.
punk::console (0.1.7):
- get_size dispatches object-governed calls through the virtual ::opunk::Console::size method
after first-use settling - subclass size overrides are honoured from every punk::console
call site
- ANSI/tput mechanisms + per-pair timing cache factored into size_via_query_mechanisms, shared
by the legacy channel-pair path and the registered provider (console_size_provider)
- integration wiring consolidated into once-latched ensure_object_integration (probe-byte store
redirect + provider registration, respecting customised providers), invoked from
default_console, console_spec_resolve lazy-require sites and the get_size object path
- legacy path returns the documented 80x24 fallback instead of erroring when undetermined
tests: WidgetishConsole subclass override returned through punk::console::get_size for both
anchored-name and object-value specs; class-level provider consultation/capability-gating with
a counting fake provider; provider registration assert. Console suites 27/27 + 10/10; punkexe
6/6, goals 8/8; full suite green except pre-existing exec-14.3.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
opunk::console (0.2.0):
- probe-byte waiting store changed from dict to array (::opunk::console::waiting_chunks) and made
pluggable via waiting_chunks_arrayvar: integrating layers redirect it to their established
cooperative store so bytes consumed by opunk::Console probe reads stay visible to active readers.
The class remains free of punk::console dependencies - redirection is the integrator's act.
punk::console (0.1.6):
- default_console redirects the opunk::console store to punk::console::input_chunks_waiting
(closing the split-store hazard that previously made opunk-level probes invisible to the
punk repl reader)
- get_ansi_response_payload performs first-use active settling for persistable console specs,
guarded by a recursion latch around settle_can_respond's own probe: every query path
(get_cursor_pos, get_device_status, ...) now pays at most one settling probe instead of a
fresh timeout per call on unsettled ambiguous consoles
punk::repl (0.1.6):
- repl::init routes default console construction through punk::console::default_console
(deduplicates creation logic and gains the store unification)
tests: store-unification and get_cursor_pos first-use settling cases in consolespec.test
(zero-emission and persistence asserts); consoleclass.test store assertions converted to array
form. Console suites 25/25 + 9/9; punkexe 6/6, goals 8/8; full suite green except pre-existing
exec-14.3.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
punk::console (0.1.5):
- settle_can_respond: layered active settling of a console's response capability, persisted on
the anchored opunk::console instance. Layer 1 certainty (input eof -> 0, no emission),
layer 2 strong-negative heuristic (plain pipe, no terminal hints -> 0, no emission - piped/CI
output streams stay clean), layer 3 active CSI 6n probe with timeout, only in the ambiguous
zone (real consoles / pipe-presenting terminals such as mintty without winpty). -force
unsettles and re-probes; -timeout_ms overrides can_respond_probe_timeout_ms (default 500).
Unmatched input consumed while waiting is preserved via input_chunks_waiting.
- get_size triggers first-use settling for persistable specs only (anchored instance name or
the auto-attached default) so unanchored object values cannot cause per-call probes
- get_ansi_response_payload only cycles console raw mode when the input channel is a
console/tty: pipe-targeted probes no longer flip the real console's mode as a side effect,
and a repeat-cycle deadlock under captured-channel environments (runtests runx) is fixed.
(Latent enableRaw_twapi/disableRaw_twapi restore asymmetry noted for future attention.)
punk::repl (0.1.5) / opunk::console (0.1.1): docs reference the active settling mechanism
(no behaviour change; probe machinery stays in punk::console so the class remains free of
that dependency)
tests: 5 new settle_can_respond cases in consolespec.test - certainty and clean-pipe settling
with zero-emission asserts, ambiguous probe timeout with emission and input-preservation
asserts, response arrival settling 1 with realistic event-loop delivery then -force
transition to 0, and get_size first-use settling. Console suites 23/23; full suite green
except pre-existing exec-14.3.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com