fix: survive the instant-exit pty race; report signal deaths - #5
Merged
Merged
Conversation
The stress workflow caught the suite flaking at ~1/80 instant-exit spawns (child writes and exits within its first millisecond): the OS pty teardown — macOS especially — can discard output still buffered at slave close, and can surface teardown as a signal-death instead of the real exit code. Reproduced locally at ~1/10 full-suite runs. Harness fixes: - attach the reader thread BEFORE spawning the child, so the drain is running from the child's first byte (narrows the race as far as userspace can; the residual kernel-side caveat is documented in docs/DESIGN.md and README known-limitations) - ExitStatus now carries the terminating signal's name; Display says 'killed by signal: ...' so harness-level kills can never be mistaken for application exit codes (ExitStatus: Clone, no longer Copy) - Screen's Debug is the compact header+text rendering; a failing Result test prints a readable screen instead of a single-line dump of thousands of cells (long enough that CI log pipelines dropped it, which is why the first stress failures were undiagnosable) Suite fixes: - every instant-exit script now ends with a stdin 'read' guard and is released with Enter only after its output is asserted — the deterministic pattern, now documented in DESIGN.md; doctests teach it - unicode-torture gained the same guard - resize-echo initializes crossterm's event source (the SIGWINCH listener) before its first draw, closing a resize-before-listener lost-signal race - fixture_bin() always refreshes fixture binaries once per process: cargo test does not relink plain bin artifacts, so an old target/<profile>/<name> from a previous cargo build silently tested stale fixture code - exit-code assertions include the full status in their message Validation: 30/30 full-suite release iterations at --test-threads=4 clean locally (previous flake rate ~1/10); signal reporting covered by a new signal-death test. Signed-off-by: Vyncint Ng <vyncint@icloud.com>
vyncint
added a commit
to DevanshGang/termlens
that referenced
this pull request
Sep 13, 2026
The label link pointed at `github.com/vyncint/temlens` (missing the `r`), which is a 404 — and vyncint#314's "Done when" asks specifically that the label link resolve, so the section did not yet do the one job it exists for. Alongside that: - Restore the missing spaces around the README link and the `)label` run-on, and drop the stray space before the comma. - Move the section below the four-projects callout so the framing note still sits directly under the intro, and use the house em-dash. - Point the DCO mention at §5 rather than restating it, and keep the section unnumbered so §1–§8 keep their numbers: the PR template links §5 and §6. - In the README, append the pointer to the sentence instead of splitting it mid-clause, since the "Three things to know" list follows immediately. Verified: both URLs return 200, `vyncint#5-developer-certificate-of-origin-dco` and `#where-to-start` match real headings, and check-readme-links.sh passes. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
vyncint
added a commit
that referenced
this pull request
Sep 17, 2026
* fix(ci): check the pull-request template's links .github/PULL_REQUEST_TEMPLATE.md linked the two checklist items a contributor is most likely to click as `../CONTRIBUTING.md`. That is right for a file living in `.github/`, and wrong for a pull-request body, which GitHub renders relative to the pull request's own URL: from `//pull/351` it resolved to `/vyncint/termlens/CONTRIBUTING.md`, a 404, on the two rules this repository blocks a merge over — the DCO sign-off and the no-AI-attribution policy. Both links are absolute now, with the anchors checked against the headings in CONTRIBUTING.md (`#5-developer-certificate-of-origin-dco`, `#6-ai-tooling-policy`), and `check-readme-links.sh` gives the template the absolute-only rule `README.md` already has, for its own URL. The gate's selftest gains a relative-template fixture and asserts the repository's own files — the template among them — still pass; `ci.yml` runs the gate over it, and CONTRIBUTING §1 lists the wider invocation. `.github/ISSUE_TEMPLATE/` was checked for the same shape: its only link is `config.yml`'s, which is already absolute. Closes #369 Signed-off-by: whiteye <62688683+maskjelly@users.noreply.github.com> * test(link-gate): make the template fixture isolate the new rule The fixture linked `../CONTRIBUTING.md`, which the gate already rejected before this branch: relative targets resolve against the repository root, and `$root/../CONTRIBUTING.md` does not exist. The expectation compares exit status only, so a fixture that goes red for the old reason satisfies it — reverting check-readme-links.sh left the selftest 7/7 green. Link `CONTRIBUTING.md` instead. It resolves from the root, so the old rule accepts it and only the new absolute-only rule can reject it. With the script reverted the selftest now fails, which is the point of it: FAIL PULL_REQUEST_TEMPLATE.md: a relative target fails (#369) exit 0, expected nonzero Same shape as readme-relative/, which links docs/DESIGN.md for exactly this reason. Signed-off-by: Vyncint Ng <vyncint@icloud.com> --------- Signed-off-by: whiteye <62688683+maskjelly@users.noreply.github.com> Signed-off-by: Vyncint Ng <vyncint@icloud.com> Co-authored-by: Vyncint Ng <vyncint@icloud.com>
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.
The stress workflow caught the suite flaking at ~1/80 instant-exit
spawns (child writes and exits within its first millisecond): the OS
pty teardown — macOS especially — can discard output still buffered at
slave close, and can surface teardown as a signal-death instead of the
real exit code. Reproduced locally at ~1/10 full-suite runs.
Harness fixes:
running from the child's first byte (narrows the race as far as
userspace can; the residual kernel-side caveat is documented in
docs/DESIGN.md and README known-limitations)
'killed by signal: ...' so harness-level kills can never be mistaken
for application exit codes (ExitStatus: Clone, no longer Copy)
Result test prints a readable screen instead of a single-line dump
of thousands of cells (long enough that CI log pipelines dropped it,
which is why the first stress failures were undiagnosable)
Suite fixes:
released with Enter only after its output is asserted — the
deterministic pattern, now documented in DESIGN.md; doctests teach it
listener) before its first draw, closing a resize-before-listener
lost-signal race
cargo test does not relink plain bin artifacts, so an old
target// from a previous cargo build silently tested
stale fixture code
Validation: 30/30 full-suite release iterations at --test-threads=4
clean locally (previous flake rate ~1/10); signal reporting covered by
a new signal-death test.
Signed-off-by: Vyncint Ng vyncint@icloud.com