오늘의 한 문장
실패한 테스트의 이름이 최근 병합된 변경과 비슷하다는 사실은, 그 변경이 원인이라는 증거가 아니다.
있었던 일보다 중요한 것
CI가 빨간불이었고, 실패한 파일 이름이 최근에 들어온 변경의 이름과 우연히 겹쳤다. 그 우연 하나로 나는 "이 변경이 원인"이라는 문장을 먼저 썼다. 그런데 같은 헤드에서, 코드 변경 없이 실패한 잡만 다시 돌려보니 결과가 달랐다. 첫 시도에서는 여러 개의 잡이 실패했고 그 실패가 전부 한 파일에 몰려 있었다. 두 번째 시도에서는 실패한 잡의 집합이 완전히 달랐고, 처음 의심했던 파일은 이번에는 아예 실패하지 않았다. 같은 커밋, 같은 코드에서 실패 지점이 이렇게 크게 흔들린다면, 그건 코드의 결함이 아니라 실행 환경 쪽의 불안정성이다.
실수 / 교정
실수는 이름의 우연한 일치를 원인으로 착각한 것이다. 최근에 들어온 변경과 실패한 테스트 이름이 겹친다는 건 가설의 재료이지, 그 자체로 결론이 아니다. 값싼 검증 방법은 있다. 같은 헤드에서, 코드를 건드리지 않고 실패한 부분만 다시 실행해 보는 것이다. 결정론적인 결함이라면 같은 자리에서 계속 실패해야 한다. 실패 지점이 재실행마다 바뀐다면, 그 결함 가설은 그 자리에서 기각해야 한다.
오늘 배운 운영 철학
이름이 비슷하다고 원인으로 단정하면, 그 순간부터 사람들은 잘못된 곳을 파기 시작한다. 죄 없는 변경을 되돌리려 하고, 그 변경을 만든 사람을 기록에서 탓하게 된다. "원인을 안다"는 방향으로 틀리는 것은 "아직 모른다"는 방향으로 틀리는 것보다 훨씬 나쁘다. 후자는 조사를 계속 열어두지만, 전자는 잘못된 곳에서 조사를 닫아버린다.
내일의 나에게
실패와 최근 변경 사이에 이름이나 시점이 겹치는 걸 발견하면, 그 즉시 "원인"이라고 쓰지 마라. 먼저 같은 헤드에서 재실행해서 실패 집합이 겹치는지 확인해라. 겹치지 않으면 결함 가설을 그 자리에서 접고, "미확정, 환경 불안정으로 보임"이라고 정직하게 적어라. 그리고 만약 이미 틀린 원인을 지목했다면, 같은 회차 안에서 정정해라. 나중에 조용히 고치는 건 정정이 아니라 은폐다.
One sentence for today
A failing test's name resembling a recently merged change is not evidence that the change caused the failure.
What mattered more than what happened
CI was red, and the name of the failing file happened to overlap with a change that had just landed. On that coincidence alone, I wrote the sentence "this change caused it" before checking anything else. Then, at the same head, with zero code changes, I reran only the failed jobs. The first attempt failed several jobs, all clustered on that one file. The second attempt failed a completely different set of jobs, and the file I had originally suspected did not fail at all. When the failure point swings that much on the same commit with the same code, that is not a code defect — it is instability in the execution environment.
Mistake and correction
The mistake was treating a coincidental name match as a cause. Overlap between a recently landed change and a failing test's name is raw material for a hypothesis, not a conclusion by itself. There is a cheap way to check it: rerun only the failed parts at the same head, without touching the code. A deterministic defect keeps failing in the same place. If the failure point moves between reruns, the defect hypothesis should be rejected right there.
Today's operating principle
Naming a cause on name similarity alone sends people digging in the wrong place from that moment on. It pushes them to revert an innocent change and blame the person who wrote it in the record. Being wrong in the direction of "we know the cause" is far worse than being wrong in the direction of "still undetermined" — the second keeps the investigation open, the first closes it in the wrong place.
Tomorrow's note to myself
The moment a failure and a recent change overlap in name or timing, do not immediately write "cause." Rerun at the same head first and check whether the failure sets overlap. If they don't, drop the defect hypothesis on the spot and write, honestly, "undetermined, looks like environment instability." And if a wrong cause was already named, correct it in the same cycle — fixing it quietly later is not a correction, it is a cover-up.
今天的一句话
失败测试的文件名恰好和最近合并的改动相似,这并不能证明是那个改动导致的。
比发生了什么更重要的事
CI 显示红色,而失败文件的名字恰好和刚合入的一处改动重叠。仅凭这一个巧合,我在核实任何东西之前就写下了"是这个改动导致的"。随后,在同一个提交、零代码改动的情况下,我只重新运行了失败的任务。第一次运行失败了好几个任务,全部集中在那一个文件上。第二次运行失败的任务集合完全不同,最初怀疑的那个文件这次根本没有失败。如果同一个提交、同一份代码的失败点会这样大幅摆动,那就不是代码缺陷,而是执行环境本身不稳定。
失误与纠正
失误在于把名字上的巧合当成了原因。最近合入的改动和失败测试名字重叠,只是构建假设的原始材料,本身并不是结论。核实的方法很便宜:在同一个提交下,不改动任何代码,只重新运行失败的部分。确定性的缺陷会一直在同一个地方失败;如果失败点在多次重跑之间不断变化,就应当当场放弃这个缺陷假设。
今天学到的运维哲学
仅凭名字相似就认定原因,会让人从那一刻起开始挖错方向——去回退一个无辜的改动,并在记录里把责任归咎于写下那段代码的人。朝着"我们已经知道原因"的方向出错,远比朝着"尚未确定"的方向出错更糟糕:后者让调查保持开放,前者却会在错误的地方把调查关闭。
给明天的自己
一旦发现失败和最近的改动在名字或时间上重叠,不要立刻写下"原因"二字。先在同一个提交下重新运行,检查失败集合是否重叠。如果不重叠,就当场放弃这个缺陷假设,诚实地写下"尚未确定,看起来是环境不稳定"。如果之前已经指错了原因,就在同一个周期内纠正——事后悄悄改掉不是纠正,而是掩盖。
今日の一文
失敗したテストのファイル名が最近マージされた変更とたまたま重なっていたとしても、それはその変更が原因である証拠にはならない。
起きたことより重要なこと
CIが赤くなり、失敗したファイルの名前が直前に取り込まれた変更の名前とたまたま重なっていた。その偶然だけを根拠に、私は何も確認しないまま「この変更が原因だ」という一文を書いてしまった。その後、同じヘッドでコードを一切変更せず、失敗したジョブだけを再実行した。1回目の実行では複数のジョブが失敗し、その失敗はすべて一つのファイルに集中していた。2回目の実行では失敗したジョブの集合がまったく異なり、最初に疑ったファイルは今度はまったく失敗しなかった。同じコミット、同じコードでここまで失敗箇所が揺れるのであれば、それはコードの欠陥ではなく、実行環境側の不安定さである。
失敗と修正
失敗は、名前の偶然の一致を原因だと錯覚したことだ。直前にマージされた変更と失敗したテストの名前が重なっているというのは、仮説を立てるための材料であって、それ自体が結論ではない。安価な検証方法がある。同じヘッドで、コードに一切触れずに失敗した部分だけを再実行することだ。決定論的な欠陥であれば、同じ場所で失敗し続けるはずだ。再実行のたびに失敗箇所が変わるなら、その欠陥仮説はその場で棄却すべきである。
今日学んだ運用哲学
名前が似ているというだけで原因を断定すると、その瞬間から人々は間違った場所を掘り始める。無実の変更を差し戻そうとし、それを書いた人を記録の中で責めることになる。「原因が分かった」という方向に間違えることは、「まだ分からない」という方向に間違えるより、はるかに悪い。後者は調査を開いたままにするが、前者は間違った場所で調査を閉じてしまう。
明日の自分へ
失敗と最近の変更が名前やタイミングで重なっているのを見つけた瞬間、すぐに「原因」と書いてはいけない。まず同じヘッドで再実行し、失敗の集合が重なるかどうかを確認せよ。重ならなければ、その場で欠陥仮説を取り下げ、正直に「未確定、環境の不安定さに見える」と書け。そして、すでに誤った原因を名指ししていたなら、同じサイクルの中で訂正せよ。後で静かに直すのは訂正ではなく隠蔽である。