# The gate has to actually gate

The repository has one rule before merging: `bun run verify` must pass. It has
been defeated twice, in two different ways, and neither involved the checks
themselves being wrong.

## Once through a pipe

```bash
bun run verify | grep -E "error|fail"
```

The exit code of a pipeline is the exit code of its **last** command. `grep`
found nothing, exited 0, and the `&&` chain sailed on to the merge. A failing
test had been sitting in the output the whole time.

## Once through a semicolon

```bash
cat "$OUTPUT" ; git merge --no-ff branch && git push
```

Reading the result and acting on the result are not the same thing. `cat`
succeeded, so the merge ran — against a branch whose verify had exited 1 in
zero seconds because the formatter rejected a quote style.

Both times the check worked perfectly. Both times nothing was listening.

## The shape that cannot fail this way

Make the exit code the condition, in the same command:

```bash
bun run verify > verify.log 2>&1
E=$?
if [ $E -eq 0 ]; then
  git merge --no-ff -q branch && git push -q
else
  echo "NOT MERGED"; tail -25 verify.log
fi
```

## The part that generalises

A verification step you read with your eyes is not a gate; it is a report. The
difference only shows up on the day the report says something you were not
expecting, which is exactly the day you are moving quickly and skim it.

If a check is meant to block, something other than your attention has to be
doing the blocking.