Report the Harper version in the startup options banner - #2263
Draft
DavidCockerill wants to merge 1 commit into
Draft
Report the Harper version in the startup options banner#2263DavidCockerill wants to merge 1 commit into
DavidCockerill wants to merge 1 commit into
Conversation
This comment has been minimized.
This comment has been minimized.
DavidCockerill
force-pushed
the
david/startup-log-version
branch
from
August 21, 2026 20:12
fa87964 to
96500b6
Compare
The banner is the block operators paste into support threads and investigation notes; the version only appeared in the separate "successfully started" line, which is frequently outside the excerpt. Sourced from the same packageJson.version that line uses so the two cannot disagree.
DavidCockerill
force-pushed
the
david/startup-log-version
branch
from
August 21, 2026 20:18
96500b6 to
e86cf0e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
Version:field to the startup options banner, so the block an operator reads — or pastes into a support thread — identifies the build it came from. Sourced from the samepackageJson.versiontheHarper <version> successfully startedmarker already uses, so the two cannot disagree.Until now the version reached stdout only via that marker, which sits above the ASCII logo and a variable number of boot lines, so any excerpt starting at the banner carried no build identity. Under
IS_SCRIPTED_SERVICEthe marker isn't printed at all (bin/run.ts:227), which makes the banner the only version on stdout for those installs.For the human reviewer
An integration boot to cover a one-line log field.
integrationTests/server/startup-banner.test.tsboots Harper and reads its stdout; the alternative was a unit test over the exportedstartupLogwith a stubbedportResolutionsand a capturedconsole.log, or no test at all. The unit version wouldn't prove the line actually reaches stdout from worker 0, which is the only property worth guarding. Cost is one boot per run — 3.9s observed, and the suite already boots Harper in most files. Reversible by deleting the file.The test's oracle is self-referential, deliberately. It compares the banner's version against the readiness marker's version. Both read the same in-process
packageJson.versionbinding, so it guards presence, format and plausible shape, never the value — it cannot catch a wrong or stale version. The alternative, comparing against the resolved distribution'spackage.json, does prove the value but couples the assertion to whichever build the harness resolved (HARPER_INTEGRATION_TEST_INSTALL_SCRIPT, or aharperpackage innode_modules, can point elsewhere), so "wrong binary under test" would read as a banner regression. One line either way — say the word if you'd rather have the value check and accept that failure mode.Field position.
Version:goes after the conditionalMode: READ-ONLYline and beforeHostname:, so the yellow read-only alert stays the first thing you see. The alternative is makingVersion:the literal first line. One-line move, but this banner's field order is the de facto operator contract, so it's worth your opinion rather than my silent choice.Console-only, not
hdb.log. The banner is a bareconsole.log, so withlogging.stdStreams: falsethe new field — like every other banner field — never lands inhdb.log; I verified this on a local boot. A support engineer holding only a customer'shdb.logfrom such an install still can't read the version. Emitting throughhdbLoggerwould fix that, but makes the version a log-format commitment the moment anything parses it, and duplicates it wherever stdStreams is on. I chose not to. Relatedly, the version now prints twice on stdout — banner plus marker — which is deliberate: the banner is the block people paste, the marker scrolls away.Where to look hardest:
readStartupStdout.startupOutput.stdoutstops accumulating at the readiness marker, and the banner is printed from worker 0 — reaching the parent's stdout over the worker forwarding channel, which is not ordered against the main thread's own marker write. Either line can therefore be absent from that snapshot, which is why the helper pollsstdout.log(always available:@harperfast/integration-testing/dist/run.js:80-83defaultsHARPER_INTEGRATION_TEST_LOG_DIRto a fresh temp dir when unset) and throws with the path and a tail rather than degrading silently.Three review findings were raised and not acted on, each refuted against source rather than deferred: an ANSI-anchoring risk on the readiness regex (the harness ANSI-strips before both its snapshot and its disk write,
harperLifecycle.js:304,320, soFORCE_COLORnever reaches what the test reads); a claim thatnpm run test:integrationleavesHARPER_INTEGRATION_TEST_LOG_DIRunset (the runner defaults it, cited above); and anode:assert/strictconformance nit (.oxlintrc.jsonandAGENTS.md:196forbid that import). That last one was a real contradiction in the repo, so it is fixed here:integrationTests/README.mdno longer tells you to write an import the linter rejects, in both the requirements list and the template. No existing integration test imported/strict, so nothing else changes.Verification
End-to-end route: new integration test, plus a live smoke.
npm run test:integration -- "integrationTests/server/startup-banner.test.ts"→ 1 passing.bin/run.tsline removed anddistrebuilt, the same test fails on the poll timeout, naming the log path. Restored and re-verified green.dist/bin/harper.js runfrom this worktree against a scratch root; banner printedVersion: 5.2.4, matching theHarper 5.2.4 successfully startedline below it andpackage.json.hdb.logunderlogging.stdStreams: false(decision 4) — console-only, unchanged from before.prettier --checkandoxlint --format stylish --quietclean on both files.Not run to completion locally:
npm run test:unit:main. It hangs indefinitely on macOS inunitTests/components/applicationSpawn.test.js("terminates a detached process tree when its owning worker is force-terminated") under the suite's--timeout 0. Reproduced identically on this branch and on amaincheckout, so it is pre-existing and unrelated — filed separately. CI's unit matrix is the gate, and it is green on all three Node versions.Complexity: medium
Review-Coverage: authored=claude; ran=gemini; adjudicated=domain; blocked=cursor-composer(not-installed),codex(exit-1); declined=cursor-grok; rounds=10 @ e86cf0e
Human-Review-Need: 3 (decisions: test-layer-choice, logdir-absent-policy, banner-field-order, version-surface, duplicate-version-emission, version-source) @ e86cf0e