Skip to content

Commit a88dc86

Browse files
authored
docs: record parallel fork budget and the mktemp-uniqueness constraint (#814)
1 parent c86c220 commit a88dc86

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

.claude/rules/perf-fork-budget.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ fork class; they are the RED test of the TDD cycle.
5353
| small-list `awk \| sort \| awk` | pure-bash filter + insertion sort | #809 (tens of items only) |
5454
| N × `mktemp` scratch files | one run-unique dir + fixed names, lazy `>>` creation | #801, #811 |
5555
| probe fork + first-use fork | probe does the real work and seeds the return slot | #802 (clock perl) |
56+
| per-worker `mkdir -p` | parent pre-creates before spawning workers (`[ -d ]` inside a worker races its siblings) | #813 |
57+
| sanitize-args pipeline on empty input | guard: skip the pipeline when the input is empty | #813 |
5658

5759
`shopt -s extdebug` for `declare -F`: enable it **inside the capture subshell
5860
only** — toggling it in the caller's shell clobbers caller state (#808).
@@ -71,10 +73,19 @@ only** — toggling it in the caller's shell clobbers caller state (#808).
7173
- **`tput cols` at startup**: returns 80 on non-tty; snapshots depend on that
7274
width. Not removable.
7375

74-
## Current budgets (plain 1-test file run, Bash 3.2 macOS)
76+
## Current budgets (Bash 3.2 macOS)
7577

76-
~3 `awk` (provider map ×2 — the counting subshell can't share its cache with
77-
the runner — plus the duplicate check), 1 `perl` ×2 clock reads (start/end;
78-
no `EPOCHREALTIME` before Bash 5), 1 `base64` capability probe, 1 `mkdir`,
79-
1 `tput`. Per-test cost is fork-free. Cold start ~50ms, ~31ms of which is
80-
sourcing `src/` (irreducible without lazy-loading, rejected in #798).
78+
**Sequential 1-test file run:** ~3 `awk` (provider map ×2 — the counting
79+
subshell can't share its cache with the runner — plus the duplicate check),
80+
`perl` ×2 clock reads (start/end; no `EPOCHREALTIME` before Bash 5), 1 `base64`
81+
capability probe, 1 `mkdir`, 1 `tput`. Per-test cost is fork-free. Cold start
82+
~50ms, ~31ms of which is sourcing `src/` (irreducible without lazy-loading,
83+
rejected in #798).
84+
85+
**Parallel 10-test file run (CI's mode):** ~21 forks — 10 `mktemp` (one per
86+
test: the unique result file; deterministic names collide because different
87+
provider args can sanitize identically and workers can't make unique tokens on
88+
Bash 3 — subshells inherit `$$` and the `RANDOM` state, and `BASHPID` is 4.0+),
89+
3 `mkdir`, 4 `rm`, 3 `awk` (#813; was 61). `wait_for_job_slot` already uses
90+
`wait -n` on Bash 4.3+ and an adaptive sleep-poll fallback — don't "fix" it.
91+
The spinner forks `sleep` ~1/s on non-tty; not worth chasing.

0 commit comments

Comments
 (0)