SAPE-24 claims three clients, each run against a real daemon. For the PHP
client that was verified once, by hand, and then left with nothing to hold it: the
repository had no CI at all, and its thirteen end-to-end tests are gated on
SAPEDB_TEST_HOST. Set it and they run; leave it unset and every one of them skips.
A skipped test and a passing test produce the same summary line. So "the suite is green" and "nobody ever set the variable" were the same observation from outside the one terminal somebody happened to run it in. The claim was not false. It was unguarded, which is a different failure and a slower one.
A workflow with two jobs: one that runs the unit suite anywhere, and one that
builds the server from source, seeds a database, starts a real sapedbd, and runs
everything — then fails if anything was skipped, rather than trusting a
summary.
It also compares the daemon's pid before and after the suite, not merely whether something answers on the port. A supervisor silently restarting a crashed daemon would still leave something listening; the pid is what tells that apart from the one process that ran the whole job. That check is the point: the suite establishes a collection and declares operations over the wire, and the thing being proved is that no restart was needed.
OK (77 tests, 198 assertions) and exited 1.
GitHub runs each run: block under bash -e. On a clean run PHPUnit prints
no Skipped: line at all, so the grep reading that count exits 1 and the
assignment took the script down — three lines before the fallback written precisely
to handle a missing count. An absent measurement must be handled, and the handler has to be
reachable to do it.destination path '/home/runner/work/sapedb/sapedb' already exists. The
clone-beside-the-checkout pattern was borrowed from the TypeScript client's workflow, where it is
right for two reasons — that repository resolves the server by a relative sibling path, and
it is not itself named sapedb. This one is. Neither reason held, and only the second
was visible.90 tests, 238 assertions, 0 skipped against a real daemon, and the pid unchanged across the run. The 13 end-to-end tests now run on every push instead of on every push where somebody remembered.