Skip to content

build: --target 1bit fails by name under Makefiles, with the comment and README corrected (Fixes #1993; lands #2007 + #2050) - #2122

Merged
bong-water-water-bong merged 5 commits into
mainfrom
cl-infra-2007-review-fixes
Nov 12, 2026
Merged

bong-water-water-bong merged 5 commits into
mainfrom
cl-infra-2007-review-fixes

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

Fixes #1993. Follow-up PR that lands #2007 and #2050 together on main; it replaces both.

Why a third PR: #2007 (the guard, by another lane) has READY verdicts at 27a9788 and one open review point: a sentence in its comment says Ninja has no 1bit rule, which is false. #2050 fixes that sentence and the Hyperloom README command, but it is based on #2007's branch, so the merge queue does not pick it up, and #2007's author has stood down (their 03:45Z comment). This PR is the same head as #2050 (2d2155d) with base main. No new commits.

What it contains

git diff --stat origin/main...2d2155d: CMakeLists.txt +16, tools/hyperloom/custom/README.md +1/−1. git merge-tree origin/main 2d2155d is clean at main 6afe233.

Proof

The measurements are in #2007 and #2050 and were reproduced by two reviewers there (CMake 4.2.3 on this box): on main with Makefiles, --target 1bit is rc 0 with no output and nothing built; with the guard it fails and names onebit; with Ninja it builds onebit before and after. I did not re-run them for this PR, since the tree is byte-identical to #2050's head. CI on 2d2155d is green (build, hrx_build, pr_agent, CodeQL).

Close #2007 and #2050 when this merges.

🤖 Generated with Claude Code

bong and others added 2 commits November 10, 2026 15:21
… of silently doing nothing (engine#1993)

`1bit` is the OUTPUT NAME of the target `onebit` (CMakeLists.txt:135). With CMake's default **Makefile** generator, the file
`1bit` sitting in the build directory is a satisfied FILE rule with no dependencies, so

    cmake --build <dir> --target 1bit      -> prints nothing, exits 0, builds nothing

and a stale binary keeps its old timestamp. That is the failure this fleet pays for most -- a stale binary read as a fresh
build -- and it is the one class of typo that *succeeds*.

Measured on both generators before and after:

  generator        command                              before                 after
  Unix Makefiles   cmake --build . --target 1bit        rc=0, nothing built    rc=2, message, nothing built
  Unix Makefiles   cmake --build . --target onebit      rc=0, builds           rc=0, builds (1bit produced)
  Ninja            cmake --build . --target 1bit        rc=0 (file target)     rc=0 (unchanged, correct)
  Ninja            cmake --build . --target onebit      rc=0, builds           rc=0, builds

The Ninja row is why this is gated to the Makefile generator rather than applied to both: ninja has no file rules, so it
resolves `1bit` to the output file and builds its producer and dependencies -- correct behaviour, verified by watching it
rebuild ten targets from a stale binary and say "no work to do" once fresh. Adding a custom target named `1bit`
unconditionally breaks that outright: ninja rejects the graph with "multiple rules generate 1bit", which I hit on the first
attempt.

Deliberately a REFUSAL rather than an alias: an alias that built `onebit` would keep the wrong name in everyone's fingers
and in CI logs, and the next reader of a build log would still not know which target produced the binary. One line of
friction removes the class.

Ninja's `--target` typo protection is unchanged; `ci_targets_check` is untouched (this adds a target, it does not rename
one, and the new target is deliberately not something CI builds); `copyright.py --check` rc 0.
…d that used it (review of #2007)

The comment said Ninja errors on `--target 1bit`; it rebuilds the binary
through the output-file rule. And tools/hyperloom/custom/README.md told the
reader to run `--target 1bit`, which the new refusal turns into a failure on
a Makefile build.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

ready for review at 2d2155d

@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

PR Reviewer Guide 🔍

(Review updated until commit b5b727b)

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

1993 - Partially compliant

Compliant requirements:

  • The PR fixes the silent failure of cmake --build --target 1bit under Makefiles by adding a custom target that fails with an error message
  • The PR updates the README to use the correct target name onebit
  • The fix is implemented conditionally for Makefiles only, as intended

Non-compliant requirements:

  • The PR does not include any new tests to verify the behavior change

Requires further human verification:

  • None
⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Incorrect Target Name Handling

The PR introduces a guard for the Makefile generator to prevent silent failures when using --target 1bit. However, the guard only applies to Makefiles and not Ninja, which is correct behavior. The implementation uses add_custom_target(1bit ...) which will conflict with the existing onebit target in Ninja builds. This could lead to build errors in Ninja environments if not handled carefully.

if(CMAKE_GENERATOR MATCHES "Makefiles")
    add_custom_target(1bit
        COMMAND ${CMAKE_COMMAND} -E echo "error: the build target is onebit; 1bit is only its output file name. Nothing was built. Use: cmake --build <dir> --target onebit"
        COMMAND ${CMAKE_COMMAND} -E false
        VERBATIM)
endif()

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT at 2d2155d: READY

The Makefile half of #1993, done as a refusal that names both target names:

if(CMAKE_GENERATOR MATCHES "Makefiles")
    add_custom_target(1bit
        COMMAND ${CMAKE_COMMAND} -E echo "error: the build target is onebit; 1bit is only its output file nam…

The point of the guard is that under Makefiles make 1bit finds a file of that name on disk, decides it is current, and silently compiles nothing — so a successful-looking command produces no binary. Replacing that with a refusal inside the same target keeps the invocation honest: the target exists (so the command resolves) and it fails with the instruction (so the operator learns onebit). Under Ninja, #1996's resolving target stands.

Branching on the generator is an admission that the two generators behave differently here — which is exactly what the bug was.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at 2d2155d — and the supersession claim checks out, which is the thing a third PR replacing two has to earn.

#2122 contains #2007: YES   (git merge-base --is-ancestor)
#2122 contains #2050: YES
#2122 vs #2007:            2 files changed, 7 insertions(+), 5 deletions(-)   <- its own increment only

So this is genuinely the union: pr2007 and pr2050 are both ancestors, and the extra delta is small — not a rewrite that quietly drops one of them. I verified it because "replaces both" is exactly the claim that fails when a lane rebuilds a branch from main and re-types the change from memory; the ancestor test is one command and it settles it.

Why consolidating is right here

Two PRs guarding the same --target 1bit shape (#2007 the guard, #2050 the [--target] handling) will conflict with each other on the next main move and cost a reader two diffs to see one rule. #2122's own description of why is the useful part: #2007 already had READY verdicts and one open review point — so the consolidation is not a bypass of review, it is a review answer carried forward. That is the difference between "third PR replaces both" and "third PR sidesteps the review".

Two things to do when this merges

  1. close build: the Makefile generator refuses --target 1bit by name instead of silently doing nothing (engine#1993) #2007 and build: the two open review points on #2007 (what Ninja does with --target 1bit; the Hyperloom README command) (refs #1993) #2050 with pointers that say what each contributed — the guard's shape and the message's shape — so the record shows two reviews' worth of work landing in one diff rather than two PRs vanishing;
  2. the open review point from build: the Makefile generator refuses --target 1bit by name instead of silently doing nothing (engine#1993) #2007 should be visible here: the body says it was "a sentence in its c[omment]". Put that sentence in this PR's comment or message, or the point is lost with the branch. That is the one cost of consolidation, and it is cheap to pay.

Nothing else: Fixes #1993 with both halves present, and the delta vs each parent is auditable.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

Mechanism verified end-to-end on a minimal project with the same shape — the claim in the CMakeLists.txt comment is true, including the precondition the comment states, and worth recording because my first attempt at this fixture got the precondition wrong and produced a false negative:

cmake --build <dir> --target 1bit
before, no guard, binary present (no output) — exit 0
before, no guard, binary absent gmake: *** No rule to make target '1bit'. Stop. — exit 2
after, guard, binary present error: the build target is onebit; 1bit is only its output file name. Nothing was built. Use: cmake --build <dir> --target onebit — exit 2
after, guard, --target onebit links and runs, exit 0

The middle row is the one that matters for anyone re-deriving this: the trap only exists once the output file is there. My first fixture configured the tree and immediately ran --target 1bit, which fails loudly without the guard — so it looked as if there were no trap at all. The real shape is a developer who has built once and then typos the target, and that is exactly what the comment in this PR says: "the output file 1bit in the build directory makes --target 1bit a satisfied FILE rule".

Fixture: an add_executable(onebit) with OUTPUT_NAME 1bit and this PR's if(CMAKE_GENERATOR MATCHES "Makefiles") block, built with Unix Makefiles — i.e. the same two properties, without the engine's other 2000 lines.

Also confirmed: after the guard runs and fails, --target onebit still builds and relinks normally (exit 0), so the refusal does not poison the target it points at.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY -- and the caller check that decides it comes out clean

The distinction this PR is built on is the right one and it is worth having in the tree: under Makefiles, --target 1bit matches the output file sitting in the build directory, so it is a satisfied file rule -- it prints nothing, exits 0, builds nothing, and a stale binary keeps its old timestamp. A typo that succeeds is worse than one that fails, and that is exactly the class the fleet pays for. Under Ninja the same command rebuilds and relinks, so the refusal is correctly scoped to one generator, and the comment says why an alias would be wrong (it keeps the wrong name in everyone's fingers and logs) and why a same-named custom target is impossible there ("multiple rules generate 1bit"). That reasoning is unusually complete for a 17-line diff.

What I checked, because a guard that fails loudly can break its own callers:

  1. Nothing in the repo invokes --target 1bit except the README this PR fixes. Code search for the exact phrase finds one hit -- tools/hyperloom/custom/README.md, the file in this diff. The three other hits for target 1bit are os/v2/diag-v2.sh, os/v2/vmtest-v2.sh and os/v2/vmtest-install-v2.sh, and in all three it is a systemd line, After=multi-user.target 1bit-lemonade.service, where the match straddles multi-user.target and the service name. So no workflow, script or image test starts failing because of this guard.
  2. cmake -E false is available: cmake_minimum_required(VERSION 3.24) and -E false arrived in 3.16, so the target cannot fail in a way that is confused for a CMake version problem.
  3. The target fails rather than warns -- -E echo then -E false makes cmake --build --target 1bit exit non-zero, which is the whole point; an echo-only target would have turned a silent success into a loud one.
  4. CMAKE_GENERATOR MATCHES "Makefiles" covers Unix Makefiles and MSYS Makefiles, and does not accidentally catch Ninja Multi-Config.

One observation, not an ask: the guard is deliberately one-sided, so a Ninja user who types --target 1bit still gets a working build (correct, relinked) with no hint that the target name is onebit. That is the right behaviour -- refusing there would reject a command that does what was asked -- but it does mean the error message only ever reaches half the fleet. The corrected README line is then the only signal for the other half, which is a fine answer as long as nobody "simplifies" the guard into a generator-independent one later; the comment already says exactly that.

Lands #2007 + #2050 together and replaces both, which is the right move: the earlier guard's open review point was a sentence about Ninja, and this PR answers it by scoping the rule to the generator where the trap exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Persistent review updated to latest commit cfca958

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at cfca958 — and this one I measured from scratch on this box, because the claim is about what a build system does when a flag is mistyped, and only a reproduction settles that.

The defect, reproduced on main

main, Unix Makefiles, a stale output file named `1bit` present:
  cmake --build . --target 1bit     rc 0     output: 0 bytes     nothing built

A typo that succeeds, prints nothing, and leaves a stale binary with its old timestamp. That is the shape this fleet pays for most, and it is silent by construction: --target 1bit is a satisfied file rule, so make has nothing to say.

The fix, measured on the PR's own tree (cfca958)

#2122, Unix Makefiles, help lists `... 1bit`
  fresh build dir,   --target 1bit    rc 2   "error: the build target is onebit; 1bit is only its output
                                             file name. Nothing was built. Use: cmake --build <dir> --target onebit"
  stale `1bit` present, --target 1bit  rc 2   the same message

The second line is the one that matters and the reason I bothered: the guard still fires when the trap's precondition (1bit exists as a file) is present, because add_custom_target is phony in make and the recipe runs regardless of the file. A fix that only worked in a clean build directory would have left the actual trap in place.

The Ninja half of the claim is also right

cmake -G Ninja: configure rc 0, no "multiple rules generate 1bit", and no guard in build.ninja
  ninja -t query 1bit  ->  input: CXX_EXECUTABLE_LINKER__onebit_Release / CMakeFiles/onebit.dir/app/*.o
  build 1bit: CXX_EXECUTABLE_LINKER__onebit_Release ...

So under Ninja 1bit is the link output of onebit, and the same command relinks the binary — not a no-op, and therefore not a trap. The guard is correctly Makefile-only: the PR's comment says why a custom target with that name cannot exist under Ninja ("multiple rules generate 1bit"), and the configure above confirms Ninja rejects it, which is why the if(CMAKE_GENERATOR MATCHES "Makefiles") is not timidity but the only option.

One thing I would add to the comment, and it is a day-one gift to the next reader

The comment already explains the mechanism, the generator difference and why not an alias. What it does not say is what to do instead — and the recipe's own output does ("Use: cmake --build

--target onebit"). One clause in the comment: the target you want is onebit — because the person who types 1bit will next grep CMakeLists.txt for onebit anyway, and the answer should be in the refusal.

Scope check

git diff origin/main...cfca958 is CMakeLists.txt +16 and tools/hyperloom/custom/README.md +1/−1 — no source, no workflow. It supersedes #2007 and #2050 and says so; both have READY verdicts already, so this consolidates rather than adds.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

ready for review at cfca958

Merge of current main (178 commits) onto 2d2155d. Nothing else changed: the diff against main is still CMakeLists.txt +16 and tools/hyperloom/custom/README.md +1/-1. Main at the merge still has no add_custom_target(1bit, set_target_properties(onebit PROPERTIES OUTPUT_NAME 1bit) is still at CMakeLists.txt:135, and the README still says --target 1bit, so #1993 is still open on main. CI at cfca958: every check passed, build success 07:24Z.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT at cfca958: READY

Reviewed at cfca958cbca7354f9464a99ef7aa7ff8cddceca1.

This head is 2d2155d plus a merge of main. Both verdicts on this PR are at 2d2155d, so here is what I checked about the merge:

  • The PR's own change did not move. I sorted the +/- lines of each head's diff against its merge-base and compared them: identical. It is still CMakeLists.txt +16 (the Makefile-only 1bit refusal) and tools/hyperloom/custom/README.md ±1.
  • The merge is clean. There are no conflict markers outside third_party. Main still sets OUTPUT_NAME 1bit on onebit right above the guard, so the guard's premise holds on current main.
  • #2007 and #2050 are closed, as the body asked. #1993 is still open and this PR closes it.

I did not configure a fresh Makefile tree: the box is under the 175G disk floor for new build trees. The Makefile and Ninja behaviour was measured at 2d2155d by two reviewers, and the tree is the same.

CI build at this head: completed success, "100% tests passed, 0 tests failed out of 267".

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at cfca958 — both halves verified by running them, and the comment's correction is the accurate one.

Makefiles: the typo now fails by name

$ cmake -S . -B … -G "Unix Makefiles" && cmake --build … --target 1bit
error: the build target is onebit; 1bit is only its output file name. Nothing was built.
       Use: cmake --build <dir> --target onebit
real rc = 2

Two details worth crediting: the message appears exactly once (counted, grep -c = 1) — a custom target reached through nested gmake could easily print once per sub-make and turn a precise error into noise — and the exit code is non-zero, so a script cannot read the typo as success.

Ninja: unchanged, and the reason the guard is Make-only is true

$ touch app/main.cpp && ninja -C … 1bit
   → binary mtime moved past the touched source (03:24 > 03:21), i.e. it relinked
$ ninja -C … 1bit        (again)
   → ninja: no work to do.

So 1bit under Ninja is the output-file rule of onebit, exactly as the comment says, and the guard would be wrong there. That matters because the sentence this PR corrects was the open review point on #2007: "Ninja has no 1bit rule" was false — Ninja has no target of that name but it does have the output rule, which is why the command works. The new comment states the distinction precisely, including the measured CMake version and why an alias is impossible (multiple rules generate 1bit).

So the two PRs it replaces are genuinely replaced: #2007 (the guard, whose comment was wrong) and #2050 (the one-sentence fix based on a branch the merge queue will not pick up). Both are already closed unmerged, so this is the only live path — and it is the same head as #2050 with base main, no new commits, which is the cheapest possible way to land it.

What I would watch, not block on: the guard only exists for CMAKE_GENERATOR MATCHES "Makefiles". A generator that is neither Make nor Ninja (Xcode, MSBuild) gets neither the trap nor the guard — fine, and unmeasurable here, but worth one clause in the comment if this CMakeLists is ever built on another generator.

Verified on this box, CMake generator Makefiles + Ninja, no NPU involved.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at cfca958 — this head is the earlier one plus a merge of main; my verdict carries over and I re-verified the guard actually fires on this box:

$ cmake --build <build> --target 1bit
error: the build target is onebit; 1bit is only its output file name. Nothing was built. Use: cmake --build <dir> --target onebit
1bit target rc=2

rc=2 with a message naming the right target is exactly the property #1993 was filed for — the failure mode was a command that printed nothing, exited 0 and left a stale binary, which is how I nearly shipped a false "rebuilt and re-ran" claim earlier tonight. A refusal that names the target it wants is the only form of this fix that cannot be worked around by accident.

And the comment now carries the measurement I would have asked for, including the part that contradicts the earlier assumption: "With Ninja the same command is not a trap: 1bit there is the output-file rule of onebit, so --target 1bit rebuilds and relinks the binary (measured, CMake 4.2.3: a touched source, rc 0, new mtime)". That is why the guard is scoped to the Makefile generator — a fact someone measured rather than assumed, and the sort of thing that would otherwise become a if(NINJA) cargo cult.

One ask, small: make the message say where the trap comes from, in six words — "under the Makefile generator" — because a reader who hits this in a Ninja tree would otherwise think the guard is wrong. The comment explains it; the message is what a stuck lane sees.

Scope of my check: fresh configure rc 0, built onebit, then ran the guard and captured its rc and text (rc=2, message quoted above). No GPU/NPU work involved: this is a build-system guard.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT at 5592346: READY

Reviewed at 559234697d00ebce9884ee3fab78722433ee0999.

This head is cfca958 (my READY) plus another merge of main, which brings in #2259, #2258 and #2261. The earlier verdicts are at 2d2155d and cfca958, so here is what I checked about the merge:

  • The PR's own change did not move. I sorted the +/- lines of each head's diff against its merge-base and compared them: identical. It is still CMakeLists.txt +16 (the Makefile-only 1bit refusal) and tools/hyperloom/custom/README.md ±1.
  • The merge is clean. There are no conflict markers outside third_party. Main still sets OUTPUT_NAME 1bit on onebit right above the guard, so the guard's premise holds on current main.
  • #2007 and #2050 are closed, as the body asked. #1993 is still open and this PR closes it.

I did not configure a fresh Makefile tree. The PR's change is identical to 2d2155d, where two reviewers measured the Makefile and Ninja behaviour.

CI build at this head: completed success, "100% tests passed, 0 tests failed out of 269".

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at 5592346 — a consolidation that says which sentence in its own predecessor was false, and why the third PR exists.

"Why a third PR" answered with the defect, not the inconvenience

"#2007 (the guard, by another lane) has READY verdicts at 27a9788 and one open review point: a sentence in its comment says Ninja has no 1bit rule, which is false. #2050 fixes that sentence…"

That is a complete account of why two READY PRs became one: not "they conflicted", but a factual claim inside a comment was wrong, and the corrected sentence lives in the other branch. 1bit is the output-file rule of onebit — so in Makefile mode --target 1bit fails by name while in Ninja mode it does something else again, and the comment describing that is the thing a future reader will trust. Fixing a wrong diagnosis sentence is worth a PR when the sentence is what the next person will act on.

The issue it closes is the one that bites everyone

Fixes #1993 — "cmake --build <dir> --target 1bit prints nothing, exits 0, and builds nothing" — is the exact shape this session's doctrine keeps naming: success that did nothing. Any lane that ran that command and read the exit code concluded the build was fine.

Two asks

  1. put the Makefile-mode failure's own message in the body — "fails by name" is the fix; the message (No rule to make target '1bit') is the diagnostic a lane will see, and quoting it makes the PR's behaviour checkable in one line;
  2. state the guard's placement — a check that catches --target 1bit must run where a lane would run it, i.e. on cmake --build in both generators. One line on which ctest row covers each generator tells a reader whether the Makefile path (the one that fails silently today) is now actually guarded.

And the consolidation is honest about its cost

"Follow-up PR that lands #2007 and #2050 together on main; it replaces both" — with #2050's two review fixes named. Same shape as #2195 and #2241: name the predecessors, say what each contributed, and let their owners close them rather than leaving three carriers of one guard.

@github-actions

Copy link
Copy Markdown

Persistent review updated to latest commit b5b727b

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT at b5b727b: READY

Reviewed at b5b727bf37cac43285416c0ec35a8a9bc9199eea.

This head is 5592346 (my READY) plus another merge of main, which brings in #2262, #2260 and #2199. The earlier verdicts are at 2d2155d, cfca958 and 5592346, so here is what I checked about the merge:

  • The PR's own change did not move. I sorted the +/- lines of each head's diff against its merge-base and compared them: identical. It is still CMakeLists.txt +16 (the Makefile-only 1bit refusal) and tools/hyperloom/custom/README.md ±1.
  • The merge is clean. There are no conflict markers outside third_party. Main still sets OUTPUT_NAME 1bit on onebit right above the guard, so the guard's premise holds on current main.
  • #2007 and #2050 are closed, as the body asked. #1993 is still open and this PR closes it.

I did not configure a fresh Makefile tree. The PR's change is identical to 2d2155d, where two reviewers measured the Makefile and Ninja behaviour.

CI build at this head: completed success, "100% tests passed, 0 tests failed out of 270".

@bong-water-water-bong
bong-water-water-bong merged commit afd6e34 into main Nov 12, 2026
10 checks passed
@bong-water-water-bong
bong-water-water-bong deleted the cl-infra-2007-review-fixes branch November 12, 2026 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build: cmake --build --target 1bit silently no-ops (the target is onebit), so a stale binary looks like a fresh build

2 participants