[Bug] Claude resists writing black-box tests, defaults to white-box internal verification instead

Resolved 💬 2 comments Opened Feb 24, 2026 by joesh Closed Mar 24, 2026

Bug Description
Claude resists writing black-box tests even when repeatedly instructed to do so. It far prefers writing tests to verify its code matches what it intended but resists checking the results/side effects of the code. I've asked it many times. Here's the most recent: ❯ still frame when parked and no video. why aren't your black-box tests catching it?

⏺ Good question. Let me trace the actual seek path end-to-end to find where the frame gets lost, and understand why the
tests are blind to it.

⏺ Read 2 files (ctrl+o to expand)

⏺ Let me also read the current test file to understand what the "black-box" tests actually verify.

⏺ Read 1 file (ctrl+o to expand)

⏺ Let me trace the full path and find where the frame gets lost. I also need to see how the real on_show_frame is wired.

⏺ Explore(Find sequence_monitor wiring)
⎿  Done (11 tool uses · 54.4k tokens · 33s)
(ctrl+o to expand)
⎿  Interrupted · What should Claude do instead?

❯ no. black box test means no tracing. you aren't managing to look at the output. you need to look at the surface or
at least the surface mock needs to see if it's called and called with a non-blank frame.

⏺ You're right. The tests check "was SEEK called?" not "does the surface have a frame?" That's white-box. A black-box
test checks the observable output — the surface.

★ Insight ─────────────────────────────────────
The fundamental test design flaw: current "b-variant" tests verify internal call sequences (SEEK called, SET_TMB
called) instead of observable output (surface has a frame). Even the Lua "a-variant" tests check a side channel
(shown_frames table) instead of the surface itself. The real on_show_frame calls EMP.SURFACE_SET_FRAME(surface, fh) —
that's what should be verified.
─────────────────────────────────────────────────

Environment Info

  • Platform: darwin
  • Terminal: Apple_Terminal
  • Version: 2.1.47
  • Feedback ID: 790b4920-b6b0-4086-84dc-cf22a0de6d68

Errors

[{"error":"MaxFileReadTokenExceededError: File content (29158 tokens) exceeds maximum allowed tokens (25000). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.\n    at IY_ (/$bunfs/root/claude:1328:7716)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-02-20T08:44:28.821Z"},{"error":"Error: Request was aborted.\n    at J2R (/$bunfs/root/claude:963:49635)\n    at next (native:1:11)\n    at GoB (/$bunfs/root/claude:5553:5172)\n    at next (native:1:11)\n    at WoB (/$bunfs/root/claude:5558:9185)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-02-20T08:53:05.646Z"},{"error":"Error: Request was aborted.\n    at J2R (/$bunfs/root/claude:963:49635)\n    at next (native:1:11)\n    at GoB (/$bunfs/root/claude:5553:5172)\n    at next (native:1:11)\n    at WoB (/$bunfs/root/claude:5558:9185)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-02-20T09:34:54.308Z"},{"error":"Error: Request was aborted.\n    at J2R (/$bunfs/root/claude:963:49635)\n    at next (native:1:11)\n    at GoB (/$bunfs/root/claude:5553:5172)\n    at next (native:1:11)\n    at WoB (/$bunfs/root/claude:5558:9185)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-02-20T15:47:18.137Z"},{"error":"Error: Request was aborted.\n    at makeRequest (/$bunfs/root/claude:358:3940)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-02-20T16:16:24.222Z"},{"error":"AbortError: The operation was aborted.\n    at unknown\n    at abortChildProcess (node:child_process:935:42)\n    at onAbortListener2 (node:child_process:35:24)\n    at abort (unknown)\n    at IJ (/$bunfs/root/claude:11286:47765)\n    at <anonymous> (/$bunfs/root/claude:11278:6952)\n    at <anonymous> (/$bunfs/root/claude:715:12022)\n    at <anonymous> (/$bunfs/root/claude:715:2434)\n    at $ (/$bunfs/root/claude:715:3284)\n    at emit (/$bunfs/root/claude:703:529)","timestamp":"2026-02-20T16:17:17.521Z"},{"error":"AbortError: The operation was aborted.\n    at unknown\n    at abortChildProcess (node:child_process:935:42)\n    at onAbortListener2 (node:child_process:…

Note: Content was truncated.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗