You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

5.0 KiB

G-085 punk::ns::cmdtrace: source-file vs live-proc line attribution option, and machine-parseable trace output

Status: proposed Scope: src/modules/punk/ns-999999.0a1.0.tm (cmdtrace, cmdtrace* trace callbacks, argdoc), src/tests/modules/punk/ns/testsuites/ns/cmdtrace.test Goal: punk::ns::cmdtrace can attribute traversed lines against either the live proc body (current corp -n based display) or the proc's originating source file (absolute path + file line numbers, when the definition location is recoverable), selectable by option with a sensible auto default - and can return its trace results as a documented machine-parseable dict (per target: attribution basis, cmdtype, per-line type/call counts, success/error/subcommand counts) instead of, or alongside, the ANSI-marked display - so the output is usable programmatically (future hotspot analysis, repl integration) and line reporting can be exact for file-defined procs even where live-relative tracing is degraded by the upstream nested-switch mis-attribution (tcl tktview 5d5b1052280c976ea3d4) or by line-continuation drift between source file and info body. Acceptance: an attribution option (spelling decided in the work, e.g. -linesource live|sourcefile|auto) defaults to current behaviour with existing cmdtrace.test passing unchanged; sourcefile mode, for a fixture proc whose definition location is known, reports marks as file path plus line numbers pinned against the actual file content - including a fixture with a backslash line continuation where live mode's known display drift is pinned alongside sourcefile mode's exact result - and degrades with a clear indication (not an error) for procs without a recoverable source location; a machine-output option (e.g. -return display|dict) returns a documented dict carrying per-target attribution basis, target name, cmdtype, line records (line -> type/calls), successcalls, errorcalls and subcommand count, asserted without parsing ANSI, with the default display return unchanged and machine mode implying no interactive pause; the upstream-mismark GAP pins are unaffected or deliberately updated; the cmdtrace argdoc documents both options; full punk::ns suite passes.

Context

Grew out of the 2026-07-14 cmdtrace investigation (punk::ns 0.6.0, commit cabde42e, ns/cmdtrace.test added):

  • Which attribution regime a traced proc currently lands in depends on how it was defined: module-loaded punk::ns procs trace as RELATIVE eval/proc frames, while procs defined at the top level of a plainly sourced script yield absolute source-typed frames with correct lines throughout. The boundary is unexplored residue from that investigation (small sourced files retain correlation even inside namespace eval; the punk::ns .tm does not).
  • In the relative regime, the upstream nested-switch mis-attribution applies (core.tcl-lang.org tktview 5d5b1052280c976ea3d4; punk-free minimal repro at scriptlib/developer/tcl_switch_traceline_repro.tcl, identical on 8.6.17/8.7a6/9.0.3): an arm body whose split pattern/body list index lands on a literal word of the switch command reports container-relative lines. In the absolute-source regime the raw probes showed no mis-attribution - so a sourcefile mode is also a practical workaround for the upstream bug.
  • The cmdtrace argdoc has long documented that line continuations in a source file make traced line numbers drift against info body lines, and suggests the rename + redefine-from-body workaround; that same trick is a candidate mechanism for deliberately forcing the live-relative regime.
  • ns/cmdtrace.test already asserts on the internal ::punk::ns::linedict data because the ANSI display is not machine-friendly - evidence the machine contract is needed.

Approach

  • auto attribution: prefer sourcefile when the target's frames report source-typed absolute lines (or the definition location is otherwise recoverable), else live. Explicit live|sourcefile override both directions.
  • Machine dict: extend rather than replace the existing ::punk::ns::linedict shape - either promote that structure to documented contract or supersede it explicitly (cmdtrace.test's marked_lines helper migrates to the contract).
  • -return dict implies -pause 0 unless -pause is explicitly supplied.
  • The sourcefile-regime boundary investigation (why module .tm procs lose correlation) belongs to this goal's groundwork and may yield a further addition to the upstream ticket.

Notes

  • Motivating consumers for machine output: hotspot/coverage analysis over per-line call counts, and repl integration (the user flagged hotspot analysis as a possible future use of cmdtrace's traversal marking).
  • cmdtrace output-channel discipline (its stdout/stderr noise) is deliberately NOT part of this goal's acceptance - it can ride the planned punk::ns comment/doc hygiene pass or a follow-on; machine mode only requires that the RETURN VALUE be clean.
  • Related: the planned punk::ns hygiene pass (gated on coverage - ns/corp.test, ansi/grepstr.test, ansi/untabify.test and ns/cmdtrace.test landed 2026-07-14 as precursors).