fix(scripts): address Copilot review round 1 on #2147

- pty.mjs: narrow the BSD argv set to {darwin, freebsd}. Grouping every
  BSD together was wrong — NetBSD's `script` takes the command through
  `-c`, so the argv form fails at `script` startup, which this smoke would
  then report as a TUI crash. Rather than add an unverified `-c` branch
  for netbsd/openbsd, they fall through to `null` and the smoke skips with
  the reason: a guessed invocation turns a clean skip into a false failure
  while looking like support.

- pty.test.mjs: "supported unless Windows" would fail `test:scripts` on
  aix/sunos/netbsd/openbsd, where a null wrapper is correct and the smoke
  skips by design. State the policy once (SUPPORTED_PLATFORMS) and branch
  on it, keeping the real-probe teeth that catch a `script` missing from
  PATH. Pin netbsd/openbsd/aix/sunos to null in scriptFlavorFor's tests
  so "unsupported" reads as the default, not a win32 special case.

- render-smoke.mjs: the @returns contract claimed a close guarantee the
  code does not give — both drain give-up branches resolve after only a
  warning, so output can be truncated and the child may still hold the
  work dir. Document the bounded fallback and name the required cleanup
  shape (removeSafe, not rmSync), since a caller "tightening" cleanup on
  the old wording would reintroduce #1801 exactly where it doesn't hold.

- AGENTS.md, clients/launcher/README.md: drop the pre-#2111 claim that the
  smokes build test-servers "on demand if it is missing". ensureTestServers
  rebuilds unconditionally, once per process — presence is not freshness.

- .github/copilot-instructions.md: mirror the survival rule, per the
  same-PR mirroring requirement. One bullet, generalized past this fix:
  a smoke must assert the thing survives, not that it started, and the
  started-then-died branch belongs in a scripts/lib test against a stub.

Signed-off-by: Cliff Hall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 21:20:52 -04:00
commit bd7297da88

View file

@ -40,18 +40,26 @@ test("scriptFlavorFor falls back to the platform when the probe says nothing", (
// BSD `script` has no --version, so failing the probe is itself the signal.
assert.equal(scriptFlavorFor({ platform: "darwin" }), "bsd");
assert.equal(scriptFlavorFor({ platform: "freebsd" }), "bsd");
// NOT every BSD: NetBSD takes the command through `-c`, and nobody has run
// either it or OpenBSD here. Guessing builds an invocation that fails at
// `script` startup, which this smoke would then report as a TUI crash.
assert.equal(scriptFlavorFor({ platform: "netbsd" }), null);
assert.equal(scriptFlavorFor({ platform: "openbsd" }), null);
// An unidentifiable `script` on linux is overwhelmingly util-linux. Guess it:
// a wrong guess fails loudly with `script`'s own usage error in the captured
// output, whereas skipping is the silence this issue exists to stop.
assert.equal(scriptFlavorFor({ platform: "linux" }), "util-linux");
});
test("scriptFlavorFor returns null where there is no script(1)", () => {
test("scriptFlavorFor returns null where there is no verified invocation", () => {
assert.equal(scriptFlavorFor({ platform: "win32" }), null);
assert.equal(
scriptFlavorFor({ platform: "win32", versionOutput: "not a thing" }),
null,
);
// Unsupported is the default, not a win32 special case.
assert.equal(scriptFlavorFor({ platform: "aix" }), null);
assert.equal(scriptFlavorFor({ platform: "sunos" }), null);
});
test("ptyCommand builds the BSD argv form", () => {
@ -146,15 +154,25 @@ test("resolvePtyWrapper wraps with the resolved flavor, or reports none", () =>
assert.equal(resolvePtyWrapper({ platform: "win32", probe: () => "" }), null);
});
test("resolvePtyWrapper resolves on this machine unless it is Windows", () => {
// Not a tautology: it runs the real probe, so a `script` that has vanished
// from PATH, or a platform nobody has tried, surfaces here rather than as an
// opaque smoke failure.
// The platforms this repo claims a verified `script(1)` invocation for. Any
// other — win32, aix, sunos, netbsd, openbsd — resolves to null BY DESIGN and
// makes `smoke:tui` skip, so asserting "supported unless Windows" would fail
// `test:scripts` on a machine where the smoke is behaving exactly as intended.
const SUPPORTED_PLATFORMS = new Set(["darwin", "freebsd", "linux"]);
test("resolvePtyWrapper resolves on the platforms we claim to support", () => {
// Not a tautology: it runs the real probe against the real machine, so a
// `script` that has vanished from PATH surfaces here rather than as an opaque
// smoke failure.
const wrapper = resolvePtyWrapper();
if (process.platform === "win32") {
assert.equal(wrapper, null);
} else {
if (SUPPORTED_PLATFORMS.has(process.platform)) {
assert.ok(wrapper, `no PTY wrapper resolved on ${process.platform}`);
assert.equal(wrapper.wrap({ command: "node" }).command, "script");
} else {
assert.equal(
wrapper,
null,
`${process.platform} is not in SUPPORTED_PLATFORMS but resolved a wrapper`,
);
}
});