Skip to content

memory(feedback): kernel-pipe vs JS-space stream ordering — TS+Bun port pattern#906

Merged
AceHack merged 1 commit intomainfrom
ops/memory-kernel-pipe-vs-js-space-stream-ordering-2026-04-30
Apr 30, 2026
Merged

memory(feedback): kernel-pipe vs JS-space stream ordering — TS+Bun port pattern#906
AceHack merged 1 commit intomainfrom
ops/memory-kernel-pipe-vs-js-space-stream-ordering-2026-04-30

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 30, 2026

Summary

Test plan

  • memory file follows the auto-memory frontmatter format (name/description/type)
  • MEMORY.md entry under 200 chars per CLAUDE.md guidance
  • CI: lint (markdownlint) passes
  • CI: lint (no conflict markers) passes

🤖 Generated with Claude Code

…rt pattern

Captures the substrate finding from PR #901 (slice 18 daily-cost-report)
Copilot P1 round 2 catch as durable memory. Per Otto-363
substrate-or-it-didn't-happen: this pattern was only living in commit
messages and review threads — now indexed + reachable via memory/.

Rule: when porting bash `$(... 2>&1)` to spawnSync, merge stdout+stderr
at the kernel pipe boundary via `/bin/bash -c "<cmd> 2>&1"`, NOT in
JS-space via `result.stdout + result.stderr` concat.

Why: kernel pipe preserves the child's chronological write ordering
across both streams. JS-space concat glues two pre-segregated buffers
in a fixed order, losing the original interleaving.

How to apply: documented in the memory file with edge cases
(shell-parse-error stacking, defensive `?? ""`, `/bin/bash` over
`/bin/sh` for bash-only features).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 30, 2026 07:39
@AceHack AceHack enabled auto-merge (squash) April 30, 2026 07:39
@AceHack AceHack merged commit fe92d71 into main Apr 30, 2026
27 checks passed
@AceHack AceHack deleted the ops/memory-kernel-pipe-vs-js-space-stream-ordering-2026-04-30 branch April 30, 2026 07:43
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a durable memory entry documenting a TS+Bun porting pitfall: preserving mixed stdout/stderr chronological ordering when translating bash $(... 2>&1) to spawnSync.

Changes:

  • Added a new memory/feedback_*.md write-up explaining kernel-pipe (2>&1) vs JS-space stdout+stderr concatenation ordering differences.
  • Added a new top-level index entry in memory/MEMORY.md pointing to the new memory file.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
memory/feedback_kernel_pipe_vs_js_space_stream_ordering_ts_bun_port_pattern_2026_04_30.md New memory capturing the porting pattern + rationale and examples.
memory/MEMORY.md Adds an index bullet linking to the new memory file.

Comment thread memory/MEMORY.md

**📌 Fast path: read `CURRENT-aaron.md` and `CURRENT-amara.md` first.** <!-- latest-paired-edit: fork-audit R/C/T diff-filter coverage + plumbing-vs-porcelain note (2026-04-29 round-10 Amara). NOTE: this comment is a single-slot "latest paired edit" marker (not a paired-edit log). Per the round-10 Amara framing the slot semantics are now explicit. -->

- [**Kernel-pipe vs JS-space stream ordering — TS+Bun port pattern (Otto, 2026-04-30)**](feedback_kernel_pipe_vs_js_space_stream_ordering_ts_bun_port_pattern_2026_04_30.md) — TS+Bun port discipline: when porting bash `$(... 2>&1)` to `spawnSync`, merge stdout+stderr via shell-side `bash -c "<cmd> 2>&1"` (preserves chronological ordering at the kernel pipe boundary), NOT `result.stdout + result.stderr` concat in JS-space (loses ordering when child interleaves writes). Origin: PR #901 slice-18 Copilot P1 round 2. Composes with `classifySpawnFailure` 4-case helper + Otto-363 substrate-or-it-didn't-happen.
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This new MEMORY.md index entry is far longer than the repo’s documented “keep entries terse / ~200 chars” guidance, which makes the index harder to scan and increases the risk of truncation issues. Consider shortening this bullet to a title + very short hook and move the detailed rationale into the linked memory file body (which already contains it).

Suggested change
- [**Kernel-pipe vs JS-space stream ordering — TS+Bun port pattern (Otto, 2026-04-30)**](feedback_kernel_pipe_vs_js_space_stream_ordering_ts_bun_port_pattern_2026_04_30.md)TS+Bun port discipline: when porting bash `$(... 2>&1)` to `spawnSync`, merge stdout+stderr via shell-side `bash -c "<cmd> 2>&1"` (preserves chronological ordering at the kernel pipe boundary), NOT `result.stdout + result.stderr` concat in JS-space (loses ordering when child interleaves writes). Origin: PR #901 slice-18 Copilot P1 round 2. Composes with `classifySpawnFailure` 4-case helper + Otto-363 substrate-or-it-didn't-happen.
- [**Kernel-pipe vs JS-space stream ordering — TS+Bun port pattern (Otto, 2026-04-30)**](feedback_kernel_pipe_vs_js_space_stream_ordering_ts_bun_port_pattern_2026_04_30.md)Port bash `2>&1` to shell-side stderr/stdout merge in `spawnSync`; never concat `stdout` + `stderr` in JS.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,76 @@
---
name: kernel-pipe vs JS-space stream ordering — TS+Bun port pattern (2026-04-30)
description: When porting bash command-substitution with `2>&1` to TypeScript via `spawnSync`, must merge stdout+stderr at the kernel pipe boundary (shell-side `2>&1`), NOT in JS-space by concatenating `result.stdout + result.stderr` — JS-space concat loses chronological ordering when child interleaves stdout/stderr writes.
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The frontmatter description reads like an absolute “never concat stdout+stderr in JS-space”, but the body later calls out cases where appending result.stderr is necessary to surface shell-side parse errors. Consider tightening the wording here to clarify the rule is about preserving child stdout/stderr interleaving (kernel-pipe 2>&1) while optionally appending result.stderr for shell diagnostics when relevant.

Suggested change
description: When porting bash command-substitution with `2>&1` to TypeScript via `spawnSync`, must merge stdout+stderr at the kernel pipe boundary (shell-side `2>&1`), NOT in JS-space by concatenating `result.stdout + result.stderr` JS-space concat loses chronological ordering when child interleaves stdout/stderr writes.
description: When porting bash command-substitution with `2>&1` to TypeScript via `spawnSync`, preserve child stdout/stderr interleaving by merging at the kernel pipe boundary (shell-side `2>&1`), not by reconstructing child output as `result.stdout + result.stderr` in JS-space; append `result.stderr` separately only when shell-side diagnostics such as parse errors must also be surfaced.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +16
const result = spawnSync("/bin/bash", ["-c", `"${path}" 2>&1`], {
encoding: "utf8",
stdio: ["inherit", "pipe", "pipe"],
});
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The example interpolates path directly into the bash -c command string. Even if callers usually pass trusted paths, this pattern is easy to cargo-cult into contexts where the value is user-influenced, creating quoting/injection risk. Consider documenting the safer pattern of passing the path as a positional parameter to bash -c (so quoting is handled without string interpolation) and note that interpolation is only acceptable when the value is fully trusted/constructed.

Copilot uses AI. Check for mistakes.
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.

2 participants