Skip to content

ci(typecheck): warning ratchet — an undefined call no longer passes silently - #375

Merged
gHashTag merged 1 commit into
mainfrom
ci/typecheck-warning-ratchet
Aug 9, 2026
Merged

ci(typecheck): warning ratchet — an undefined call no longer passes silently#375
gHashTag merged 1 commit into
mainfrom
ci/typecheck-warning-ratchet

Conversation

@gHashTag

@gHashTag gHashTag commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Negative audit of every gate — the follow-up to the wave-65 pipefail finding: a green check means nothing until it is proven able to redden. I injection-tested each gate:

gate injection result
zig-exec break a gen ✅ detected
C-exec (compile) break a gen ✅ detected
C-exec (runtime) failing assert ✅ detected — t27_assert is __builtin_trap, so failure is SIGILL, not exit 0
typecheck call an undefined function 🔴 NOT detected

The hole

t27c downgrades a call to an undefined function to a warning and prints Typecheck OK (0 errors, 1 warnings) with exit 0. The gate grepped only for Typecheck OK, so the corpus could acquire undefined calls silently.

The fix: a warning ratchet

Failing on any warning isn't yet possible — 47 of 107 specs carry pre-existing warnings (788 total). So each spec's current count is pinned, and the gate fails when a count grows. A newly introduced undefined call, in any spec, now reddens the gate.

Counts were verified deterministic across repeated runs, and the baseline was generated with t27c built from t27 master — the same compiler CI uses.

It also guards the baseline itself: if the table doesn't cover every spec (a new spec that skipped it), the gate fails and names the gap — same shape as the wave-55 icarus coverage guard.

Verified three ways

  • healthy corpus → exit 0 (107 specs pinned, corpus has 107)
  • injected undefined_function_xyzcaught, spec named
  • unpinned new spec → caught (baseline covers 107 but the corpus has 108)

Lower a pinned number whenever a spec's warnings are fixed; never raise one.

🤖 Generated with Claude Code

…silently

Negative audit of every gate (the follow-up to the wave-65 pipefail
finding: a green check means nothing until it is proven able to redden).
Injection-tested each gate; two behaved, one did not:

  zig-exec        break a gen -> DETECTED
  C-exec compile  break a gen -> DETECTED
  C-exec runtime  failing assert -> DETECTED (t27_assert is
                  __builtin_trap, so a failure is SIGILL, not exit 0)
  typecheck       call an UNDEFINED function -> NOT DETECTED

t27c downgrades a call to an undefined function to a WARNING, and prints
'Typecheck OK (0 errors, 1 warnings)' with exit 0. The gate grepped only
for 'Typecheck OK', so the corpus could acquire undefined calls silently.

Failing on any warning is not yet possible -- 47 of 107 specs carry
pre-existing warnings (788 total). So pin each spec's CURRENT count and
fail when it GROWS. A newly introduced undefined call, in any spec, now
reddens the gate. Counts were verified deterministic across repeated
runs, and the baseline was generated with t27c built from t27 master --
the same compiler CI uses.

Also guards the baseline itself: if the table does not cover every spec
(a new spec that skipped it), the gate fails and names the gap -- the
same shape as the wave-55 icarus coverage guard.

Verified three ways: healthy corpus exits 0; an injected
undefined_function_xyz call is caught with the spec named; an unpinned
new spec is caught.

Lower a pinned number whenever a spec's warnings are fixed; never raise.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@gHashTag
gHashTag merged commit 540d61c into main Aug 9, 2026
4 checks passed
@gHashTag
gHashTag deleted the ci/typecheck-warning-ratchet branch August 9, 2026 04:52
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.

1 participant