Repository navigation
/track review: repetition safety gate, process cleanup, bounded presentation - #421
Merged
Merged
Conversation
…on its own target Review of #416/#420 found commands that /track (and /watch) started at once and repeated every interval without asking: - `echo x > ~/.zshrc 2>/dev/null`: the shared classifier excused every redirect in a command once `>/dev/null` appeared anywhere; `>|` was split as a pipe. Paste review labelled the same text read-only. - `env rm -rf …`: `env` is read-only on its own but runs its operand. - Anything classified network: `npm publish`, `npm login`, `npm audit fix`, `npm x`/`pnpm dlx`/`bun x`, `ssh host rm …`, `scp`, `rsync`, `curl -X POST`, `curl -o file`, plain `wget`. - `git -c core.fsmonitor=… status`, `GIT_EXTERNAL_DIFF=… git diff`, `--ext-diff` (run arbitrary programs) and `git log --output=…` (writes files). pasteGuard now judges each redirection's target (descriptor duplication and the null/standard-stream devices are not files) and treats `>|` as a redirection. repeatSafety.ts adds the repetition gate on top of the classifier: network commands start at once only as read-only probes; env prefixes, wrappers and git program options ask first; file-writing options, --fix/--write/snapshot updates, --watch modes, scp/rsync and power control are refused. `2>&1` is no longer mistaken for a background job. Network targets are remote unless they are this computer. Refs #393, #416, #420
… after wiring - When a sample's shell exits, the close handler cancelled the KILL fallback even if other members of its process group were still running. A child that ignored TERM and closed its output survived `/track stop` (verified with a pid probe; the new test fails without the fix), and a stray process left by a finished sample piled up on every refresh. On close, anything still in the group now gets TERM, then KILL after the grace period; that timer keeps a closing window alive for at most the grace period so nothing is left behind. - #420's refresh-start event now fires after the sample's handlers are attached, so a listener that throws cannot leave a child without them. - A tracker whose directory disappeared said `spawn /bin/sh ENOENT`; it now names the directory and keeps trying at its interval. Refs #393, #416, #420
…esult rows - Above the composer each active tracker had its own row, repeating its block's status; eight trackers took eight rows. More than two now share one summary row (`4 trackers · 1 failing · /track opens the manager`). - The state marks (◉ ■ ‖ ◌) ignored Safe glyphs; they now use ASCII there, in the block and the manager. - Live rows split and sanitized the whole 200 kB result on every frame (1–3 ms per frame with eight large trackers); the first rows and line count are now computed once per result (~0.5 ms). - The confirmation for an unknown /track command says "Track …?", not "Watch …?". - Live PTY tests: four trackers at once (slow, failing, missing command, large output) with `refreshing…`, a resize and `/track stop all` ending every process; Bash and Fish trackers finding a PATH change made after startup. Refs #393, #416, #420
This was referenced Oct 18, 2026
Flaky CI at the cause: task exit verdict, race-free private-root removal, stalled-file teardown
#422
Merged
Merged
raiseCatError
changed the base branch from
fix/v021-track-review-hardening
to
dev
October 18, 2026 14:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Review of #416 and #420 together. Stacked on #420;
/trackstays in v0.21, window-owned.Findings and fixes
Safety gate (commands /track and /watch started at once and repeated without asking)
echo x > ~/.zshrc 2>/dev/null>/dev/nullexcused every redirect; paste review said read-only)ls >| outenv rm -rf …,env -i …,FOO=1 df,LD_PRELOAD=… dfnpm publish,npm login,npm audit fix,npm x …,pnpm dlx …,bun x …ssh host rm -rf x,curl -X POST,curl -d,curl -o file, plainwget,gopher://scp,rsyncrsync -nasks)git -c core.fsmonitor=… status,GIT_EXTERNAL_DIFF=… git diff,--ext-diffgit log --output=f,sort -o,find -fprint,tree -o,yq -i,jest -u,--fix,--write,--watchshutdown,reboot,halt,poweroff,systemctl rebootnpm test 2>&1ping 8.8.8.8,ping nasRead-only probes still start at once:
ping/dig/nslookup/host/traceroute,nc -z, a curl GET/HEAD to stdout or-o /dev/null,wget -O -/--spider,npm view/outdated/audit.&>stays refused: dash,/bin/shon Debian/Ubuntu, reads it as a background job.Process lifecycle
/track stop(reproduced with a pid probe). On close, anything left in the group now gets TERM, then KILL after the grace period. That timer keeps a closing window alive for at most 1.5 s.spawn /bin/sh ENOENT; it now names the directory and keeps retrying.Presentation
#420 itself: reviewed. Re-entrant rendering:
render()is synchronous and only reads the scheduler, and every emit happens after scheduler state is consistent. Stale references: a deletedtrackBlocksentry is only read throughget(id)with a stopped fallback. Duplicate finalization:stop()emits once,record()ignores stopped trackers, and the window's exit unsubscribes beforedispose(). No defects found beyond the event ordering above.Tests
tests/trackSafety.test.ts(new): redirects, wrappers, git options, file-writing options, network probes vs senders, remote detection.tests/track.test.ts: leftover processes after stop and after a finished sample (fails without the fix), the missing-directory message, Safe-glyph marks, the summary row.tests/trackLive.test.ts(real PTY): four trackers at once (slow withrefreshing…, failing, missing command, large output), a resize,/track stop allending every process; Bash and Fish trackers seeing a PATH change made after startup.Docs:
docs/development/track-live-command-refresh.md, physical QA 5.7–5.11, CHANGELOG.Refs #393, #410, #416, #420