Skip to content

Reliability: Fish test homes (#403), superseded classifications (#408), multi-row progress redraws (#388) - #412

Merged
raiseCatError merged 2 commits into
devfrom
fix/v021-reliability
Oct 18, 2026
Merged

raiseCatError merged 2 commits into
devfrom
fix/v021-reliability

Conversation

@raiseCatError

Copy link
Copy Markdown
Owner

Stacked on #411 (design doc). Merge #411 first; GitHub then retargets this PR to dev.

What and why

#403: Fish test teardown race (test fixture, not a product leak). On a home with no generated completions, an interactive Fish starts fish_update_completions detached:

  • Fish 4.x checks $__fish_cache_dir/generated_completions, Fish 3.x $__fish_user_data_dir/generated_completions.
  • The orphaned Python process writes about 1,400 files into the test home after the shell exits, which races rmSync (the CI ENOTEMPTY).
  • Production keeps Fish's normal one-time behavior with the person's own directories.

Fix:

  • scripts/test-shell-home.mjs marks that generation as done in test homes. The runner, LiveSandbox and the fixtures that start Fish with their own home use it.
  • The runner no longer passes ambient XDG_DATA_HOME/XDG_CACHE_HOME/XDG_STATE_HOME to tests. Under a wrapper that sets a shared cache, test shells had been writing there.
  • No retries were added.

#408: queued-highlight classification (a production race, plus a test race).

  • Every prompt marker's shell knowledge cleared SemanticService's cache and resolved in-flight lookups as unknown. A stored command whose lookup was in flight when the next prompt arrived (a fast queue) kept the unclassified color for good.
  • A superseded lookup is now asked again against the new knowledge, at most 3 times. A stale answer is still never cached.
  • The test had also raced the real shell's startup knowledge. It now waits for that knowledge and for the lookups it started, instead of one setImmediate.

#388: multi-row progress redraws.

  • AnsiOutputParser handled \r and current-line erases but ignored row movement, so each frame of a multi-row progress display became permanent lines.
  • Programs can now redraw their own recent rows in a bounded live region:
    • Supported: CSI A/B/E/F, ESC M/D/E, save/restore (ESC 7/8, CSI s/u), CSI J 0/1 and CSI K 0/1/2.
    • The region never reaches above the newest NMSh-written line (command header, notice, earlier command) or more than the PTY's height (OutputBuffer.setScreenRows).
    • A command resumed from a journal is fenced to its own rows.
  • Absolute row positioning is not mapped and keeps today's behavior. Copy and search see the final rows, as a terminal would show them.

Tests

Each new test fails on the unfixed code and passes with the fix:

  • shellAdapters: a prepared Fish home starts no generator. The negative control finds the generator.
  • shellIntelligence: a superseded lookup is answered from the new knowledge. queuedHighlight: a stored command whose lookup was superseded still ends classified (real SemanticService). Old code: never recolored, and settled unknown.
  • ansiLiveRegion: 10 tests, including the Inline multi-line ANSI progress redraws can accumulate duplicate transcript lines #388 fixture through a real zsh PTY, interleaved log lines, fences, split sequences, resume, and 10,000 frames in about 35 ms. The old parser fails 9 of 10; the tenth is the documented unchanged absolute-positioning case.

Further runs:

  • Flaky: queuedHighlight composer/queue classification is not settled after one event-loop turn #408 tests: 16/16 passes in two concurrent loops.
  • All 59 test files touching the parser, OutputBuffer, the presenter or copy payloads: green.
  • Full npm run verify locally:
    • The first run used a too-long temp root on the external drive. That failed the runner's own short-root check plus the tmux and socket tests, for environmental reasons only.
    • Re-run with a short root, those pass. The remaining live-PTY timeouts under full-suite load on this 8 GB Mac pass when run alone.
    • CI is the exact-head gate.

Not verified

Physical terminal checks are listed in docs/testing/v021-physical-qa.md (section 1) and have not been run.

Refs #403, #408, #388, #410

…w redraws

#403: an interactive Fish on a fresh home starts its man-page completion
generator detached; it outlived test shells and raced home removal. Test
homes now mark that generation as done (Fish 3 and 4 locations), and the
runner no longer passes ambient XDG data, cache and state directories to
tests. A regression asserts no generator starts.

#408: newer shell knowledge resolved in-flight classifications as unknown,
so a stored queued command could keep the unclassified color. A superseded
lookup is now asked again against the new knowledge (bounded); stale answers
are still never cached. The highlight tests wait for the shell's startup
knowledge and for the lookups they started instead of one event-loop turn.

#388: the output parser ignored row movement, so every frame of a multi-row
progress display stayed in the transcript. Programs can now redraw their own
recent rows (cursor up/down, save/restore, partial erases), never above
NMSh's lines or more than a screen height; absolute positioning keeps the
previous behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant