Skip to content

test(harness): fail-closed lifecycle for bounded probe runner - #2682

Merged
chaliy merged 9 commits into
mainfrom
codex/syntax-diagnostic-budget
Oct 11, 2026
Merged

chaliy merged 9 commits into
mainfrom
codex/syntax-diagnostic-budget

Conversation

@chaliy

@chaliy chaliy commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What changed

Test-only, one file: threat_model_tests.rs (+211/-33). Reworks the shared run_command_bounded lifecycle per the review on #2680:

  • Retention truncated BEFORE extending: the sample buffer never passes the 8192 cap (was: extend-then-truncate kept a chunk over).
  • Interrupted reads retried; real reader errors end capture with partial bytes kept and a new read_error flag — never relabeled as clean EOF.
  • Exact-cap-then-EOF is not oversize; only real excess sets the flag.
  • Reaping bounded inside a finite 5s grace; no unconditional wait() past the cleanup deadline (targeted allow documents why the lint suggestion would reintroduce the hang).
  • timed_out retained as recorded, never recomputed; drain 2s + reap 5s graces documented against the execution deadline.
  • TM-DOS-136 regression gains !read_error and the corrected 8192-byte cap text.
  • Bounded selftests: exact-cap, cap+1, scripted Interrupted/error pipes, timeout kill+reap (~2s), overflow flag.

Does not touch #2681 distinct run_bounded_probe helper.

Before / After

Before: reader errors read as clean EOF; retention could exceed the cap by a chunk; kill-path wait() unbounded; no lifecycle selftests.
After: threat_model 219 passed (only pre-existing macOS nesting abort skipped, identical on unmodified code); error 14, partial_parse 11 green; fmt plus clippy -D warnings clean.

Risk

  • Test-only change. No production code touched.

Checklist

  • Tests added or updated
  • Backward compatibility considered (internal test harness)

macOS bash 3.2 reports -c input as line 0, modern GNU bash as line 1.
Compare diagnostic shape with line number normalized.
…gression

A long -c ARG0 stamped on every report line could evict the structural
payload out of the 1 KiB diagnostic budget. Truncate the shell name to 64
chars first so 'syntax error ...' always survives; renumber the threat entry
to TM-DOS-136 (main already owns 135 via #2674); add a bounded-child
regression exercising the exact finding shape (multiline token x long ARG0)
at two scales.
The 64-char cut mangled long script paths (breaking the oracle's path
replacement and hiding which script failed). Widen to 256 chars with a
16-char tail: realistic paths print verbatim with attribution suffixes
(': eval') intact, while a kilobyte-scale ARG0 still cannot evict the
structural payload out of the 1 KiB total. The total stays the enforced
bound.
All five branch commits already reached main via squash merges (#2675, #2677); conflicting files take main's reviewed state.
The scaled multiline-token x long-ARG0 regression now asserts the whole harness contract at both scales (200/2000 lines x 8 KiB ARG0): no watchdog timeout, raw child exit 2, no output-cap overshoot, finished reader threads, and effective stack=4096/cpu=10 caps read back from the launcher. Shape and 1 KiB assertions unchanged.
run_command_bounded cleanup per lifecycle review: truncate retention before extending (retention never passes the 8192 cap); retry Interrupted, fail closed with partial bytes on real reader errors (new read_error field, never relabeled as EOF); exact-cap EOF is not excess; reap inside a finite 5s grace, never an unbounded wait; timed_out retained as recorded; drain 2s + reap 5s graces documented against the execution deadline. Consumer regression gains !read_error and the corrected 8192-byte cap text. Bounded selftests: exact-cap, cap+1, Interrupted/error scripted pipes, timeout kill+reap, overflow flag.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 1221b7f Commit Preview URL

Branch Preview URL
Oct 11 2026, 09:00 AM

@chaliy

chaliy commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Review of exact candidate 1221b7f against the full post-merge lifecycle review (6106968187).

The cap-before-copy, exact-cap EOF distinction, Interrupted retry, real-read-error flag and bounded try_wait reaping address the prior concrete implementation defects. The documented execution deadline plus 2-second drain and 5-second reap grace is honest; keep that distinction in the evidence.

Remaining proof required before declaring the lifecycle review resolved:

  1. Add the retained-pipe negative case explicitly requested in the previous review. A direct child exiting while a bounded descendant holds stdout/stderr must return a failed/incomplete result within the documented total budget. Keep the descendant and its cleanup under an outer deadline and prove cleanup, rather than leaving a sleeper or reader indefinitely alive. Preserve a passing direct-child timeout/reap case. Cover the unavailable/failed reap verdict through a deterministic safe seam if real OS failure cannot be induced safely.
  2. The successful-capture path still calls reader.join() without a completion guard. Receipt of the final channel message is not itself proof the thread is terminal. Use a bounded completion check before joining, marking incomplete if the join cannot be established safe within the stated lifecycle budget; avoid replacing this with another unconditional wait. Add an elapsed-total assertion to the timeout and retained-pipe tests, not just result flags.
  3. The new child selftests invoke run_command_bounded directly, bypassing the CPU/stack limit launcher. In particular the builtin busy loop currently has only a wall watchdog. Apply and verify finite CPU/stack bounds to these child probes while retaining the cap and wall/cleanup limits. The scripted in-memory reader tests are useful, but also demonstrate that a real reader error becomes an incomplete failure at the parent boundary.

These are test-harness lifecycle/proof requirements, not a request to reopen any independently closed product finding. Keep the current branch and additive history; no force-push, test weakening, duplicate PR or CI waiver. Read full issue comments, formal reviews and inline threads. The skipped macOS misconfiguration case remains partial local evidence, not a full-gate waiver. Final proof still needs green required checks for the final head, actual squash merge SHA/ancestry, exact-merged producers and successful assertion exits with durable file logs.

@chaliy
chaliy merged commit 2853d86 into main Oct 11, 2026
33 checks passed
@chaliy
chaliy deleted the codex/syntax-diagnostic-budget branch October 11, 2026 09:28
chaliy added a commit that referenced this pull request Oct 11, 2026
…#2683)

## What changed

Test-only, one file: threat_model_tests.rs. Closes the lifecycle review
on #2682 without touching #2681 distinct run_bounded_probe helper:

- Bounded join gate: readers join only after all channel receipts (a
receipt proves its thread finished every blocking call; sending is the
last act before return). Missing receipts skip the join and fail
incomplete; panicking readers fail visibly via join error. std offers no
timed join; the gate plus elapsed-total assertions are the documented
termination proof.
- Reap extracted into a poll seam (reap_with_grace) with deterministic
verdict unit tests: immediate, delayed, never-exits (bounded 50ms), and
poll-error cases.
- Timeout/overflow selftests run under the shared fail-closed launcher
(new run_raw_bounded) so the effective stack=4096/cpu=10 bounds are
applied and read back, with elapsed-total bounds (2s+2s+5s budget).
- Existing bounded_helper_flags_retained_pipes reused and strengthened:
elapsed proof (returns without waiting for the 30s sleeper), read_error
distinction, outer-deadline documentation.

## Before / After

Before: unconditional join past the grace; reap untestable without OS
fakery; selftests bypassed the launcher; no elapsed proofs.
After: threat_model 220 passed (only pre-existing macOS nesting abort
skipped, identical on unmodified code); error 14, partial_parse 11
green; fmt plus clippy -D warnings clean.

## Risk

- Test-only change. No production code touched.

## Checklist

- [x] Tests added or updated
- [x] Backward compatibility considered (internal test harness)
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