Skip to content

builder: test the guest console for kernel output rather than a version string - #63

Merged
Oichkatzelesfrettschen merged 1 commit into
mainfrom
builder-mach-kernel-console-discriminator
Jul 31, 2026
Merged

Oichkatzelesfrettschen merged 1 commit into
mainfrom
builder-mach-kernel-console-discriminator

Conversation

@Oichkatzelesfrettschen

Copy link
Copy Markdown
Owner

A correction to my own PR #59, found by probing the mechanism instead of reasoning about it.

The defect

PR #59 added a discriminator so that zero Mach matches in a transcript could not be read as zero Mach errors. It tested for gnumach|mach operating system|mach [0-9]+\.[0-9].

I booted the base on a disposable overlay with console=com0 and measured what actually arrives. The version string appears exactly once in 18796 bytes — in the /etc/issue login banner a getty writes:

  Minty Hurd  (? console)
  GNU-Mach 1.8 + Hurd-0.9 -- amd64

login:

No kernel line carries it. Kernel output looks like this:

ACPI:
 rsdp = 0xbffe1c52
APIC entry=0xffffffffca121ba6 end=0xffffffffca121bf2
IOAPIC 0 configured with GSI 0-23
IRQ override: pin=11 gsi=11 trigger=LEVEL polarity=HIGH
RTC time is 2026-07-31 06:54:01
timer calibration... done
module 0: pci-arbiter --host-priv-port=...

So a serial port that reaches a getty while the kernel writes to VGA yields a version string and no kernel message — exactly the arrangement the falsifier exists to exclude. The check would have called that console observable.

Second defect in the same line

A serial console terminates lines with CRLF, so every line after the first begins with the previous line's carriage return. My first corrected pattern anchored at column zero and found 0 matches in a transcript containing 22 such lines. The anchor now absorbs the leading carriage return and the ACPI report's indentation.

Transcript Matches
Real console=com0 boot 22
Firmware/GRUB only 0
Login banner only 0

What the probe settled for ROADMAP 73b

Falsification criteria were stated before the run:

Criterion Result
A update-grub writes console=com0 onto the multiboot line pass — all three generated entries, including recovery
B A Mach kernel message then reaches serial.log pass — 338 -> 18796 bytes, full kernel boot
C The guest still answers SSH pass — 40s after reboot

The change lives in the disposable overlay, so 73b needs no re-cut of the base and no rebinding of the lock, its status, or its closure. The Hurd's /usr/bin/console does report a timeout once com0 owns the console; the boot continues through runlevel 2 and sshd starts.

An unrelated finding the probe surfaced

The first probe run produced no serial.log at all. Cause: the local gnu-hurd-docker:latest image was built 2026-07-26 and its entrypoint contains zero occurrences of QEMU_SERIAL_LOG against 6 in the working tree — it predates PR #59 entirely, and the probe silently ran a stale entrypoint.

That is the hazard PR #62's builder_container block exists to make visible, now demonstrated as live rather than hypothetical. It also means the next real build run must verify the image matches the tree before drawing conclusions from it.

Evidence

  • tests/builder-batches/executor-selftest.py gains a login-banner-only transcript case; it fails against the previous pattern.
  • Green: lint, validate, links (426/0), all three batch selftests, build-run-postconditions, builder-lock-selftest, builder-batch-evidence-check.
  • evidence/builder-batches/README.md and ROADMAP 73b record the measurement.

Assisted-by: Claude Code (claude-opus-5[1m])

…on string

The console discriminator matched `gnumach|mach operating system|mach N.N`,
and a measured transcript of a guest booted with console=com0 carries that
string exactly once, in the /etc/issue login banner a getty writes; no kernel
line carries it. A serial port that reaches a getty while the kernel writes to
VGA therefore produced a version string and no kernel message, which is the
arrangement the falsifier exists to exclude, so the check would have reported an
unobserved falsifier as an observable one. The pattern now matches lines only
the kernel writes -- the APIC entries, the IOAPIC GSI configuration, the IRQ
overrides, the RTC time, the timer calibration, and the multiboot module echo --
and it is anchored past the carriage return a CRLF serial console leaves at the
start of every line, without which a column-zero anchor matches nothing in a
transcript full of kernel output. It finds 22 lines in the measured transcript,
zero in a firmware-only one, and zero in a login-banner-only one.

The probe that measured this also settles how to reach the observation:
GRUB_CMDLINE_GNUMACH="console=com0" plus update-grub inside a disposable overlay
writes console=com0 onto all three generated multiboot lines, the guest answers
SSH 40 seconds after the reboot, and the transcript grows from 338 to 18796
bytes. The base is untouched, so roadmap 73b needs no re-cut and no rebinding of
the lock.

Assisted-by: Claude Code (claude-opus-5[1m])
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@Oichkatzelesfrettschen
Oichkatzelesfrettschen merged commit d4b156d into main Jul 31, 2026
2 checks passed
@Oichkatzelesfrettschen
Oichkatzelesfrettschen deleted the builder-mach-kernel-console-discriminator branch July 31, 2026 07:04
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 44e4595d-60cc-4efe-82fa-9eb2f1eb6e87

📥 Commits

Reviewing files that changed from the base of the PR and between 574d77f and 194cc19.

📒 Files selected for processing (4)
  • ROADMAP.md
  • evidence/builder-batches/README.md
  • scripts/execute-builder-batches.sh
  • tests/builder-batches/executor-selftest.py

📝 Walkthrough

Mechanism

  • scripts/execute-builder-batches.sh now matches GNU Mach kernel markers, including APIC, IRQ, RTC, timer calibration, and multiboot module lines.
  • The matcher accepts leading carriage returns and whitespace. It no longer uses the generic GNU Mach version string.
  • tests/builder-batches/executor-selftest.py adds a login-banner-only transcript case.

Behavioral effect

  • A console=com0 transcript is accepted only when kernel output reaches the serial console.
  • Firmware/GRUB-only and login-banner-only transcripts produce zero matches.
  • A version-only transcript is reported as a getty/VGA configuration where the Mach output was not observed.

Evidence and validation

  • Runtime probe: real console=com0 boot produced 22 kernel-line matches.
  • Negative probes: firmware/GRUB-only and login-banner-only transcripts produced zero matches.
  • Disposable-overlay probe confirmed GRUB configuration, SSH availability, and transcript growth from 338 to 18,796 bytes.
  • Self-test coverage was updated in tests/builder-batches/executor-selftest.py.
  • Build, lint, and hardware/silicon validation: not evident in PR.

Risk and reviewer focus

  • Review the kernel-marker list for false positives and compatibility with GNU Mach output variants.
  • Preserve CRLF and leading-whitespace handling in the serial transcript matcher.
  • Confirm the documentation in evidence/builder-batches/README.md and ROADMAP.md remains consistent with the executable discriminator.

Walkthrough

The change tightens serial-console validation. The executor now requires GNU Mach kernel markers, tolerates CRLF and indentation, rejects login-banner-only transcripts, and tests the behavior with a getty-console scenario. Roadmap and evidence documentation describe the validation procedure.

Changes

Serial console kernel-output validation

Layer / File(s) Summary
Console validation specification
ROADMAP.md, evidence/builder-batches/README.md
The validation procedure now defines disposable-overlay GRUB setup, serial transcript contents, kernel-line matching, CRLF handling, and login-banner exclusion.
Kernel output detection and regression coverage
scripts/execute-builder-batches.sh, tests/builder-batches/executor-selftest.py
The executor matches kernel-specific GNU Mach output with whitespace-tolerant rules. The self-test verifies that getty output does not mark the console as scanned.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

The serial line carries the proof,
Kernel marks stand under scrutiny.
Banner text stays outside the truth,
CRLF bends without mutiny.
The self-test guards the route.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch builder-mach-kernel-console-discriminator

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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