Skip to content

fix(ci): the nightly runtime proof asks the emulator what it verified - #787

Merged
stephrobert merged 2 commits into
mainfrom
fix/740-the-night-asks-what-the-emulator-verified
Sep 21, 2026
Merged

stephrobert merged 2 commits into
mainfrom
fix/740-the-night-asks-what-the-emulator-verified

Conversation

@stephrobert

Copy link
Copy Markdown
Owner

Summary

The runtime job ran the four dataplane suites, the leftovers doorstep, and nothing else of guard.sh. Both local reproductions of those same suites call guard.sh verification before the emulator stops — leg.sh and day2.sh — so a claim the emulator itself published as broken reddened a workstation and never a night.

runtime-proof is the gate #736 wanted a green night from before tagging, and a green there did not say the claims held.

Measured before arming it

A gate that starts red teaches people to ignore it, and #731 is about exactly that. On 2026-09-15, after #741 closed the one claim breaking under OVN, the incus-ovn leg answers:

held=58 broken=0 unreadable=0 repaired=0

The step is if: always() and runs before the emulator stops, because the counters and the claims die with the process (#670).

What the falsification taught, and it is the better half of this change

The test was three strings.Contains over the workflow text. Both mutations went straight through it:

mutation why it passed
comment the step out every name stays in the file, so a grep-shaped test stays green while the night asks nothing
if: always() == false it contains if: always()

Neither defect was visible from reading the test. Now:

  • readWorkflow drops whole-line YAML comments, so the test reads steps rather than text. Whole-line only, on purpose: a # inside a value is part of the value;
  • the step's if: is compared as a whole line, so a longer expression that merely starts the same way cannot satisfy it.

Both mutations bite now.

Type of change

  • Bug fix
  • Chore / tooling

Checklist

Always

  • mise run check passes, and mise run prepush in full
  • No new external Go dependency
  • internal/core still knows no provider — untouched
  • Nothing in the diff could be written identically for another provider — it is this repository's own CI
  • mise run testplan was run. conformance is not played, and this says so rather than leaving the box blank: the diff adds one workflow step, one test and one falsification spec. No route, no handler, no response shape changed, so a conformance leg would re-prove the previous commit. The step this adds is itself a conformance call, and it will run on the next scheduled night.

When a model wrote a substantive part of this

  • An Assisted-by: trailer names the tool and the model version
  • N/A on mise run conformance, for the reason stated just above
  • No field name is involved; the command added is the one leg.sh and day2.sh already call, read from those scripts

When a route is added or changed

N/A.

When behaviour a client can observe changes

N/A — nothing a client sees changes. What changes is what the night asks before it stops.

When .github/workflows/ is touched

  • Every action pinned to a full 40-character SHA — unchanged by this diff
  • step-security/harden-runner is the job's first step — unchanged
  • permissions: least-privilege — unchanged
  • No job renamed
  • The exit-code contract holds: the step runs guard.sh verification, whose non-zero reddens the job, which is the whole point

When a machine runtime is involved

  • The step runs inside the runtime job, which boots machines under incus-ovn; the figure quoted above comes from that leg
  • Nothing the emulator did not create is touched — the step only reads /_feint/
  • The run leaves nothing behind — the step is a read, and the leftovers doorstep that follows is unchanged

Related issues

Closes #740

🤖 Generated with Claude Code

The `runtime` job ran the four dataplane suites, the leftovers doorstep, and
nothing else of guard.sh. Both local reproductions of those same suites call
`guard.sh verification` before the emulator stops — leg.sh and day2.sh — so a
claim the emulator itself published as broken reddened a workstation and never
a night. `runtime-proof` is the gate #736 wanted a green night from before
tagging, and a green there did not say the claims held.

Measured before arming it, because a gate that starts red teaches people to
ignore it and #731 is about exactly that: on 2026-09-15, after #741 closed the
one claim breaking under OVN, the incus-ovn leg answers
`held=58 broken=0 unreadable=0 repaired=0`.

The step is `if: always()` and runs before the emulator stops, because the
counters and the claims die with the process (#670).

**What the falsification taught, and it is the better half of this change.**
The test was written as three `strings.Contains` over the workflow text, and
both mutations went straight through it:

- commenting the step out keeps every name in the file, so a grep-shaped test
  stays green while the night asks nothing. The test now drops whole-line YAML
  comments before reading, so it reads steps rather than text;
- `if: always() == false` CONTAINS `if: always()`. The test now compares the
  step's `if:` as a whole line, so a longer expression that merely starts the
  same way cannot satisfy it.

Neither defect was visible from reading the test. Both mutations bite now.

Closes #740

Assisted-by: Claude Code (claude-opus-5)
@stephrobert
stephrobert merged commit 775c6f8 into main Sep 21, 2026
31 checks passed
@stephrobert
stephrobert deleted the fix/740-the-night-asks-what-the-emulator-verified branch September 21, 2026 07:58
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.

The runtime job of runtime-proof.yml never runs guard.sh verification, so a claim the emulator reported broken has never reddened a night

1 participant