一键导入
sidecar-smoke-suite-reveals-upstream-bugs
A downstream sidecar smoke suite can expose upstream bugs that unit tests miss; fix upstream first, then land the suite.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
A downstream sidecar smoke suite can expose upstream bugs that unit tests miss; fix upstream first, then land the suite.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
A TRefCountPtr/TSharedPtr member in a UE class needs the pointee's full definition, not a forward decl.
When WSL's mirrored networking fails and falls back to "None", plus /etc/wsl.conf has generateResolvConf=false, the distro has no DNS; fix both layers.
When a Windows shell (PowerShell/cmd) feeds a bash script into WSL, CRLF line endings can corrupt the first shell builtin; force LF or pipe via a temp file.
Before "fixing" a recurring error, check git log to see if it was already fixed upstream — the working tree may just be stale.
Always add a space after URL brackets in Markdown to prevent 404 errors with special characters.
Plan a Python 3 modernization sweep (f-strings, super(), type hints) as a series of mechanical PRs, not one mega-PR.
| name | sidecar-smoke-suite-reveals-upstream-bugs |
| description | A downstream sidecar smoke suite can expose upstream bugs that unit tests miss; fix upstream first, then land the suite. |
| tags | ["testing","cross-repo","sidecar","ci","regression"] |
You maintain an upstream library / build tool / framework and a separate sidecar repository that consumes it end-to-end against real fixture projects (an integration workspace, example repo, regression harness, plugin host, ...).
You are either:
Signal phrases: "it works in upstream's own tests but breaks here",
"the unit tests never hit this path", "the failure only shows up
on macOS / on ubuntu-22.04 / without python on PATH".
This skill is about what to do with the discovery, not about how to paper over it. For the paper-over-then-clean-up flow, see reverse-cleanup-after-upstream-fix.
Unit tests in the upstream repo protect the functions they cover, but they rarely exercise:
#!/bin/sh wrapper, an
exec python -m … launcher) — because the unit test process
already has python / sh / the right PATH.python
vs python3, GNU sed vs BSD sed, /usr/bin/gcc being Apple
Clang.python on PATH, macOS 14 does not.py_library
alone and py_test alone; neither catches a launcher bug that
only manifests when a py_test runs a real subprocess that
itself runs a shell.A sidecar repo that builds real fixtures with the real tool on a real host finds these bugs by existing. The moment you add a second language / a second platform / a second Python minor, the uncovered path light up.
Symptom pattern from a real session (blade-build ↔ blade-test, 2026-04-27):
py_basic suite (py_library + py_test, 24 lines
of Python) to the blade-test sidecar failed on macOS host with
exit 127 at greeter_test's launcher.src/blade/builtin_tools.py emitted
exec python -m … into the .pex-style launcher shell. macOS
14 has no python, only python3. No upstream unit test
covered the emitted shell text.If you catch this kind of discovery and just work around it in
the sidecar (hardcode BLADE_PYTHON_INTERPRETER=python3 in the
suite's BUILD file, or skip py_test on macOS), you lose twice:
Four steps, in strict order:
The first question is not "how do I make this green". It is "is this reachable as an upstream unit test?" If yes, the bug has a permanent home in the upstream suite and every future consumer is protected; if no, you're about to accept a regression gap.
# upstream unit tests should be able to assert on the artifact the
# downstream is tripping over — the emitted shell, the generated
# Makefile, the rendered config file. If they can't, that's a
# coverage gap the fix PR should close.
cd upstream/
grep -rn 'def test_.*launcher\|bootstrap\|shebang' src/tests/
If there's no existing unit test for the emitted artifact, the upstream fix PR adds one — that's the permanent plug. Without it the same class of bug will bite the next sidecar.
The cross-repo PR order is:
upstream fix PR ── merge ──▶ sidecar suite PR
(#1096) (#2)
Never the reverse. If you open the sidecar PR first:
If you must work in parallel (e.g. to prove the fix), keep the sidecar PR in draft until the upstream fix is merged and released (for sibling-repo sidecars, "merged to the consumed ref" is usually enough — see pitfalls).
The unit test lives in upstream, not in the sidecar. It asserts on the specific artifact that the downstream tripped over:
# upstream: src/tests/unit/builtin_tools_test.py
def test_py_binary_launcher_uses_python3_not_python(self) -> None:
pylib = _make_minimal_pylib(...)
generate_python_binary(out_path, pylib, main='mod.main')
bootstrap = out_path.read_text()
# regression guard: the launcher must not hardcode `python`
self.assertNotIn('exec python -m', bootstrap)
self.assertIn('${BLADE_PYTHON_INTERPRETER:-python3}', bootstrap)
Two properties make this useful:
BLADE_PYTHON_INTERPRETER, defaults to python3"), not
a bisected symptom ("exit 127 on macOS").Once upstream is fixed and released, the sidecar suite should be
the simplest possible reproduction: no env vars, no platform
ifs, no comments that explain around the (now-fixed) bug. The
suite's value is that it stays boring forever:
# sidecar/suites/py_basic/BUILD
py_library(name = 'greeter', srcs = 'greeter.py', visibility = 'PUBLIC')
py_test(name = 'greeter_test', srcs = 'greeter_test.py', deps = ':greeter')
A sidecar suite that carries if platform == 'darwin': ... or
env = {'FOO_PY': 'python3'} has been captured by the bug it
was supposed to expose, and future regressions in the same
neighborhood will be silently absorbed.
Real sequence from 2026-04-27, blade-build ↔ blade-test:
py_basic suite; blade test //suites/py_basic:greeter_test
fails with exit 127 on macOS 14 (no python on PATH).src/blade/builtin_tools.py emits
exec python -m … verbatim.grep -rn builtin_tools_test src/tests/unit/ → 0 hits.exec "${BLADE_PYTHON_INTERPRETER:-python3}" -m …src/tests/unit/builtin_tools_test.py, 5 tests that
build a minimal .pylib and assert the bootstrap text.BUILD
file stays the 20-line default; no BLADE_PYTHON_INTERPRETER=…
escape hatch.Diff shape of each side:
upstream PR #1096: src/blade/builtin_tools.py (1 line fix)
src/tests/unit/builtin_tools_test.py (5 new tests)
sidecar PR #2: suites/py_basic/BUILD, greeter.py, greeter_test.py
(no env knobs, no platform conditionals)
Six months later a reader opening the sidecar sees a boring contract suite, not a bug scar.
export FOO=bar to the suite's runner "so the test still
runs while we wait for upstream". This defeats the purpose — a
sidecar's value is being a faithful consumer, not a
hardened one.py_basic is worth more than
a 2000-line port of upstream's own tests, because the former
exercises the composition that upstream unit tests skip./usr/bin/gcc).