Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .claude/skills/ci-gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7837,3 +7837,54 @@ regression, and expect the regression to be a defect you did not know
about rather than a mistake in the change.

Related: §241, a guard whose precondition had stopped holding.

## 310. The repository already wrote the correct form, by hand, next door

`gen-verilog` mapped `>>` to Verilog's `>>` unconditionally. Verilog's
`>>` fills with zeros however the operand is declared; the arithmetic
shift is `>>>`. On the CORDIC kernels this is a wrong gate, not a wrong
number: simulated on the actual generated module,
`cordic_x_next(100, -64, shift=2)` returned **-16268** where the spec, C
and Zig all say **116**.

The decisive evidence was not in the compiler. It was in the corpus:

generated Verilog, all 559 modules: 2 occurrences of `>>>`
...and both were inside string literals
those string literals: this project's own hand-written golden
CORDIC RTL, which writes `y0 >>> 1`
for the identical rotation

**The project knew the right operator and the backend emitted it zero
times.** A hand-written reference sitting in the corpus is an oracle the
generator can be measured against, and it costs one grep.

When a backend and a hand-written artefact in the same repository
disagree about the same construct, that is not a matter of taste. Look
for the artefact first: `grep` for the construct in the specs and in
`docs/`, and see whether a human ever wrote it out.

## 311. Acceptance could not have caught any of it

Four defects were fixed in one pass. Not one moved an acceptance number:

| defect | what it did | `cc` / `zig` / `iverilog` |
|---|---|---|
| `while (c) : (step)` | the step became the whole body | unchanged |
| suffix dropped | `1u64 << n` shifted at u32 and panicked | unchanged |
| `>>` on signed | filled with zeros, CORDIC did not converge | unchanged |
| truncated test | reported OK in the backend that runs tests | unchanged |

Every one produced output the target compiler was happy with. **A gate
that asks "does it compile" cannot see any defect whose whole nature is
that it compiles**, and the four above are the entire interesting class:
the compiler agreed, and the program was wrong.

What did see them: a second implementation to disagree with (the C
backend against the Verilog one), a hand-written artefact to compare to
(§310), and simulating the emitted module instead of reading it. Two of
the four were found by fan-out audits told to prefer findings the target
compiler ACCEPTS -- the instruction that made them look in the right
place.

Related: §262, what the comment was hiding.
11 changes: 11 additions & 0 deletions docs/now/2026-08-30-the-oracle-was-in-the-corpus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NOW -- The oracle was in the corpus (2026-08-30)

## Two lessons from the signed-shift fix (Refs #2868)

- `gen-verilog` mapped `>>` to Verilog's `>>`, which fills with zeros however the operand is declared; the arithmetic shift is `>>>`
- simulated on the actual generated module: `cordic_x_next(100, -64, shift=2)` returned -16268 where the spec, C and Zig all say 116
- the decisive evidence was in the CORPUS, not the compiler: all 559 generated modules held 2 occurrences of `>>>`, and both were inside string literals holding this project's own hand-written golden CORDIC RTL, which writes `y0 >>> 1` for the identical rotation
- the project knew the right operator and the backend emitted it zero times; a hand-written reference in the repository is an oracle, and it costs one grep
- four defects fixed this pass and NOT ONE moved an acceptance number: the step-as-body, the dropped width suffix, the logical shift, the truncated test
- every one produced output the target compiler was happy with, so a gate asking "does it compile" could not see any of them
- what did see them: a second backend to disagree with, a hand-written artefact to compare against, and simulating the module instead of reading it
Loading