Skip to content

os: prepare-stick stages an NPU model directory, so the release check can ask the NPU - #818

Merged
bong-water-water-bong merged 3 commits into
mainfrom
1bit/prepare-stick-npu-model
Nov 2, 2026
Merged

bong-water-water-bong merged 3 commits into
mainfrom
1bit/prepare-stick-npu-model

Conversation

@bong-water-water-bong

@bong-water-water-bong bong-water-water-bong commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Why

The c20 live boot on hardware (2026-11-02) reported RESULT: PASS (19 checks, no failures) with one row that could not be asked:

SKIP  chat-npu : no onebit NPU entry is listed by Lemonade, so there is nothing to ask

That is not a fault of the candidate. os/mini/init.sh registers every onebit model on the stick with Lemonade —
/data/models/*.gguf as <name>-1bit (HRX) and /data/models/*/model.q4nx as <directory>-1bit with
"onebit_backend": "npu"
— and the stick carried only the 0.6B GGUF, so there was no NPU entry to list. The mechanism
already existed; nothing ever put an NPU model on the stick. prepare-stick had --model FILE.gguf and no counterpart for
the engine's NPU format, which is a directory (model.q4nx + tokenizer + config).

Net effect while it stays that way: the release check never asks the NPU on hardware, so the only NPU evidence a board run
produces is the hw-gate's npu row — the Lemonade→NPU serve path is unproven there.

The change (one file, os/mini/prepare-stick.sh)

--npu-model DIR copies the directory into data/models/<name>/, where init.sh then registers it as <name>-1bit with
the NPU backend, and chat-npu picks it up through the listing it already reads.

  • The directory name is the entry name. --npu-model ~/models/npu/Qwen3-0.6B-NPU becomes the entry
    Qwen3-0.6B-NPU-1bit, which is the catalogue's own id for the NPU build of that model. A name that already ends in
    -1bit would register as …-1bit-1bit, so it is refused — in the pre-flight block, before the partition is mounted
    and before an ssh key or a key line is written.
  • cp -RL. On a build box the model directory is symlinks into the FLM install; the stick needs the bytes, and a
    dangling link would fail at load time on the console where nobody can see why.
  • --check proves it read-only: model.q4nx present with the same byte count as the source; the copy holds no
    dangling symlink
    and no symlink at all; and it prints the entry the stick will register.
  • Sizes are compared with stat -L (pi-prs's review): stat -c %s reports a link's own length, so a symlinked
    source compared wrong and a correct stick was declared broken. Fixed for --npu-model and for the pre-existing
    --model gguf assertion, which had the same bug; the model … (N bytes) line now reports the file's size too.
  • Usage block says an image file's data partition is the image's 2 GiB (os: the live stick's /data is 2 GB (351 MB free after boot) - no catalogue model can be pulled on the live appliance #706), so the 0.6B GGUF and an NPU model
    directory do not both fit in one image prep; on a stick they do.
  • Nothing else changes: no new dependency, no change to the GGUF --model path, no change to init.sh or
    release-check.sh.

Verified — end to end on throwaway copies of the c20 image (never the stick)

cp --sparse=always work/os/1bit-os.img /var/tmp/ps-*.img, at c137261:

case result
--npu-model a directory of 5 symlinks (the shape cp -RL exists for) copy 695260276 B; 13 PASS / 0 FAIL; --check rc=0 (was FAIL + rc=1)
--npu-model a real directory 13 PASS / 0 FAIL, incl. model.q4nx … 683820936 bytes, no dangling symlink, real files, no symlinks, registers as the entry 'Qwen3-0.6B-NPU-1bit'
--model a symlinked gguf copy 396705472 B, PASS, and the write line now names the file's size (was 42 bytes)
--check on a prepared image same assertions, rc=0, nothing written
--npu-model name already ending in -1bit rc=1 before mounting, message names the rename; --check afterwards shows no key was written
refusals missing dir → not a directory; no model.q4nx → carries no model.q4nx; no argument → --npu-model needs a directory
the check's own picker against the registered id pick '[^"]*-NPU-1bit' on {"id":"user.Qwen3-0.6B-NPU-1bit"} → user.Qwen3-0.6B-NPU-1bit

Row counts move with the flags: 13 with --ssh-pubkey + --npu-model, 14 with --key as well.

Testing note for anyone repeating the blocker: a symlink placed directly in /var/tmp cannot be followed by root on
this box (fs.protected_symlinks: sticky world-writable dir, symlink owner ≠ follower, dir owner ≠ symlink owner) and looks
like a code failure — the symlinks have to sit in a normal directory to exercise this path.

bash -n clean; tools/copyright.py --check rc=0. Not yet run: a live boot with the NPU model on the stick — that is
the next hardware run, and the point of the change is that chat-npu will then either PASS with a tok/s or FAIL with the
engine's own reason instead of skipping.

… can ask the NPU

1bit-release-check's chat-npu row SKIPped on the c20 hardware boot (2026-11-02) with 'no onebit NPU entry is listed by
Lemonade'. Not a defect of that run: the NPU route needs a model, the stick carried only the 0.6B GGUF, and Lemonade lists
only what it can load - so there was nothing to ask. init.sh already registers every /data/models/*/model.q4nx as
'<directory>-1bit' with onebit_backend npu; prepare-stick simply never put one there.

--npu-model DIR copies the directory (dereferencing symlinks: on a build box it is symlinks into the FLM install, and a
dangling link fails at load time on the console) into data/models/<name>/, where init.sh registers it. The directory name
is the entry name, so the catalogue ids (Qwen3-0.6B-NPU-1bit, ...) are what to name it; a name already ending in -1bit is
refused before anything is mounted, and the --check assertions prove model.q4nx matches the source byte count, the copy
holds no dangling symlink and no symlink at all.
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

PR Reviewer Guide 🔍

(Review updated until commit b3928aa)

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

706 - Partially compliant

Compliant requirements:

  • The PR introduces --npu-model functionality to prepare-stick.sh to stage NPU model directories
  • The PR ensures that NPU models are copied into /data/models/<name>/ where init.sh registers them as <name>-1bit with the NPU backend
  • The PR ensures that chat-npu will be able to run by having a valid NPU model on the stick

Non-compliant requirements:

  • The PR does not implement the automatic resizing of /data partition to the end of the device as described in the ticket
  • The PR does not write the result into /data/boot.log as described in the ticket

Requires further human verification:

  • The actual resizing of the /data partition and writing to /data/boot.log needs to be verified on the hardware
  • The release check behavior change needs to be verified on hardware to confirm chat-npu runs with the smallest NPU entry when space allows
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Data Partition Resizing

The PR does not implement the required resizing of the /data partition to the end of the device as specified in the ticket. The ticket requires that on first boot of a live stick, the /data partition should be grown using sgdisk/parted + resize2fs to allow model downloads. This functionality is missing from the PR.

#                   [--model FILE.gguf]... [--npu-model DIR]... [--check] [--force]
#
# Prepares a 1bit OS stick or image from any Linux box: puts your SSH public keys where Dropbear reads
# them, sets Lemonade's API key, and copies models into the models directory - GGUFs, and NPU model
# directories (a directory holding model.q4nx, the engine's own NPU format) - then REMOUNTS THE
# PARTITION READ-ONLY and proves what it wrote. Everything it refuses, it refuses before writing.
#
# The data partition is found the way the image describes it, never by a fixed offset: `sfdisk -d`
# reads the GPT, the partition with the Linux filesystem type (and, when there is more than one, the
# one named 1BIT-DATA) is the one, and its start sector is matched against the kernel's own partition
# nodes. The same code path therefore handles an image file (a loop device) and a real stick.
#
# Why the assertions exist: appending to Lemonade's lemond.conf is how the API key gets in, and the
# stock file has ended without a final newline. Appended naively, "LEMONADE_API_KEY=..." glues itself
# to the last line - "#LEMONADE_ADMIN_API_KEY=LEMONADE_API_KEY=xxx" - which Lemonade ignores, so the
# stick looks prepared and answers nothing (candidate 10, 26 Oct). This tool writes a newline first, and
# then checks, read-only, that the file holds exactly one key assignment, that the assignment is the key
# it was given, that there is no stray NUL byte, and that the SSH files have the modes Dropbear demands.
#
#   prepare-stick.sh /dev/sdb --mint --ssh-pubkey ~/.ssh/id_ed25519.pub --model qwen3-0.6b.gguf
#   prepare-stick.sh /dev/sdb --npu-model ~/models/npu/Qwen3-0.6B   # name the directory for the entry you want
#   prepare-stick.sh work/out/1bit-os.img --key "$(openssl rand -hex 24)" --ssh-pubkey my.pub
#   prepare-stick.sh /dev/sdb --check            # assertions only, nothing is written
#
# Space: an IMAGE file's data partition is the image's 2 GiB until it is written to a device and grown (#706), so a
# 0.6B GGUF (396 MB) and an NPU model directory (664 MB) do not both fit in one image prep. On a stick they do.
#
# --npu-model: the engine's NPU format is a DIRECTORY (model.q4nx + tokenizer + config), and init.sh
# registers every /data/models/*/model.q4nx as `<directory name>-1bit` with onebit_backend npu. So the
# directory name is the model's name: `--npu-model ~/models/npu/Qwen3-0.6B` becomes the entry
# `Qwen3-0.6B-1bit` on the stick. Without an NPU model on the stick, Lemonade lists no NPU entry and
# `1bit-release-check`'s chat-npu row can only SKIP - the NPU route is then never asked on hardware.
#
Missing Boot Log Writing

The PR does not implement writing the result of the data partition resizing into /data/boot.log as specified in the ticket. This is a required step to document the changes made to the partition layout.

#                   [--model FILE.gguf]... [--npu-model DIR]... [--check] [--force]
#
# Prepares a 1bit OS stick or image from any Linux box: puts your SSH public keys where Dropbear reads
# them, sets Lemonade's API key, and copies models into the models directory - GGUFs, and NPU model
# directories (a directory holding model.q4nx, the engine's own NPU format) - then REMOUNTS THE
# PARTITION READ-ONLY and proves what it wrote. Everything it refuses, it refuses before writing.
#
# The data partition is found the way the image describes it, never by a fixed offset: `sfdisk -d`
# reads the GPT, the partition with the Linux filesystem type (and, when there is more than one, the
# one named 1BIT-DATA) is the one, and its start sector is matched against the kernel's own partition
# nodes. The same code path therefore handles an image file (a loop device) and a real stick.
#
# Why the assertions exist: appending to Lemonade's lemond.conf is how the API key gets in, and the
# stock file has ended without a final newline. Appended naively, "LEMONADE_API_KEY=..." glues itself
# to the last line - "#LEMONADE_ADMIN_API_KEY=LEMONADE_API_KEY=xxx" - which Lemonade ignores, so the
# stick looks prepared and answers nothing (candidate 10, 26 Oct). This tool writes a newline first, and
# then checks, read-only, that the file holds exactly one key assignment, that the assignment is the key
# it was given, that there is no stray NUL byte, and that the SSH files have the modes Dropbear demands.
#
#   prepare-stick.sh /dev/sdb --mint --ssh-pubkey ~/.ssh/id_ed25519.pub --model qwen3-0.6b.gguf
#   prepare-stick.sh /dev/sdb --npu-model ~/models/npu/Qwen3-0.6B   # name the directory for the entry you want
#   prepare-stick.sh work/out/1bit-os.img --key "$(openssl rand -hex 24)" --ssh-pubkey my.pub
#   prepare-stick.sh /dev/sdb --check            # assertions only, nothing is written
#
# Space: an IMAGE file's data partition is the image's 2 GiB until it is written to a device and grown (#706), so a
# 0.6B GGUF (396 MB) and an NPU model directory (664 MB) do not both fit in one image prep. On a stick they do.
#
# --npu-model: the engine's NPU format is a DIRECTORY (model.q4nx + tokenizer + config), and init.sh
# registers every /data/models/*/model.q4nx as `<directory name>-1bit` with onebit_backend npu. So the
# directory name is the model's name: `--npu-model ~/models/npu/Qwen3-0.6B` becomes the entry
# `Qwen3-0.6B-1bit` on the stick. Without an NPU model on the stick, Lemonade lists no NPU entry and
# `1bit-release-check`'s chat-npu row can only SKIP - the NPU route is then never asked on hardware.
#
Incorrect NPU Model Directory Validation

The validation for NPU model directories does not properly check if the directory name would result in an invalid entry name. The current check only prevents names ending in -1bit, but does not ensure that the resulting entry name would be valid for Lemonade registration. This could lead to entries that are not properly registered.

for d in $NPUMODELS; do
    [ -d "$d" ] || die "npu model $d is not a directory (the NPU format is a directory, not a file)"
    [ -s "$d/model.q4nx" ] || die "npu model $d carries no model.q4nx; that is the engine's NPU model file"
    name=${d%/}; name=${name##*/}
    [ -n "$name" ] || die "npu model $d has no directory name"
    case "$name" in
        *-1bit) die "the directory name '$name' already ends in -1bit, and init.sh registers <directory>-1bit: rename it to '${name%-1bit}' so the entry is '$name'" ;;
    esac
done

@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: CHANGES at f36215f (one assertion is wrong on the exact case cp -RL exists for)

I ran it end to end on throwaway copies of the c20 image (cp --sparse=always work/os/1bit-os.img /var/tmp/ps-*.img, never the stick, /dev/sda never opened).

The blocker: --npu-model fails its own size assertion when the source directory holds symlinks — which is the
build-box case the PR's own rationale names ("on a build box the model directory is symlinks into the FLM install").

source dir: /var/tmp/npu-link-0.6B, 5 files, all symlinks into ~/models/npu/Qwen3-0.6B
$ sudo -n os/mini/prepare-stick.sh /var/tmp/ps-link-tprs.img --npu-model /var/tmp/npu-link-0.6B …
  npu      models/npu-link-0.6B (5 files, 695260276 bytes)      <- the copy is right
  PASS  models/npu-link-0.6B has no dangling symlink (the bytes are on the stick)
  PASS  models/npu-link-0.6B is real files, no symlinks
  FAIL  models/npu-link-0.6B/model.q4nx is missing or a different size
prepare-stick: 1 assertion(s) failed on /dev/loop16p2; this stick would not work as it is     rc=1

The copy is provably correct — the file on the stick is 683820936 bytes and holds no symlink. The failure is in the
comparison: stat -c %s does not dereference, so the source side is the link's own length.

$ stat -c %s  /var/tmp/npu-link-0.6B/model.q4nx      -> 45          (the link target string)
$ stat -Lc %s /var/tmp/npu-link-0.6B/model.q4nx      -> 683820936   (the file)
$ stat -c %s  <stick>/models/npu-link-0.6B/model.q4nx -> 683820936

os/mini/prepare-stick.sh:412-413 compares those two against each other, so any --npu-model directory built from
symlinks — i.e. every FLM install — prepares fine and then declares the stick broken. One-line fix: stat -Lc %s on
the source in both the if and the ok message. The same one-liner is owed in the GGUF loop at line 401
([ "$(stat -c %s "$f")" = "$(stat -c %s "$m")" ]), where it is pre-existing rather than introduced here: a symlinked
--model x.gguf fails the same way.

Your body's verified case used a real directory (~/models/npu/Qwen3-0.6B-NPU, 5 real files), so this is the one shape
the test did not take — and it is the shape cp -RL is there for.

Everything else checks out, reproduced here:

  • real directory (~/models/npu/Qwen3-0.6B, 5 files): npu models/Qwen3-0.6B (5 files, 695260276 bytes) — the same
    byte count the body records — then 14 PASS / 0 FAIL (the body says 13; my count is 14 on two runs) including
    model.q4nx is there, same size as the source (683820936 bytes), no dangling symlink, real files, no symlinks,
    and registers as the entry 'Qwen3-0.6B-1bit'.
  • --check on that prepared image → rc 0, 14 PASS, same assertions, "nothing was written".
  • refusals, all rc 1 and before the mount (the target does not even have to exist):
    --npu-model /tmp → not a directory (the NPU format is a directory, not a file); a directory with no
    model.q4nx → carries no model.q4nx; --npu-model with no argument → --npu-model needs a directory;
    a directory named fake-1bit → already ends in -1bit … rename it to 'fake' so the entry is 'fake-1bit'.
  • the registration claim is the code's: os/mini/init.sh:365-368 registers every /data/models/*/model.q4nx as
    <dir>-1bit with recipe_options.onebit_backend=npu, and release-check.sh:498 asks pick '[^"]*-NPU-1bit', so a
    directory named …-NPU is what chat-npu picks up. That is the mechanism, not a new one.
  • bash -n clean, tools/copyright.py --check rc 0 (checked on my worktree at this head).

One number to know, not a defect: on an image file the data partition is the image's 2 GiB, so after this model the
run ends at free space on the data partition: 78M. On the stick it grows to the device (#706), so the release flow is
fine, but prepping an image with both the 0.6B GGUF (396 MB) and an NPU model does not fit — worth one line in the
usage block if that is a path anyone takes.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

Fix verified on this box, so it is a copy-paste rather than a re-derivation. Three one-word changes, all in
os/mini/prepare-stick.sh — the two NPU ones are the blocker, the GGUF one at :401 is the same latent bug and is
pre-existing:

@@ -398,7 +398,7 @@
-    [ -f "$f" ] && [ "$(stat -c %s "$f")" = "$(stat -c %s "$m")" ] &&
+    [ -f "$f" ] && [ "$(stat -c %s "$f")" = "$(stat -Lc %s "$m")" ] &&
@@ -409,8 +409,8 @@
-    if [ -s "$f/model.q4nx" ] && [ "$(stat -c %s "$f/model.q4nx")" = "$(stat -c %s "$d/model.q4nx")" ]; then
-        ok "models/$name/model.q4nx is there, same size as the source ($(stat -c %s "$d/model.q4nx") bytes)"
+    if [ -s "$f/model.q4nx" ] && [ "$(stat -c %s "$f/model.q4nx")" = "$(stat -Lc %s "$d/model.q4nx")" ]; then
+        ok "models/$name/model.q4nx is there, same size as the source ($(stat -Lc %s "$d/model.q4nx") bytes)"

With that applied to f36215f (not pushed — my worktree only), on throwaway copies of the c20 image:

case before after
--npu-model = real directory (~/models/npu/Qwen3-0.6B) 14 PASS, rc 0 14 PASS, rc 0
--npu-model = directory of symlinks (the FLM-install shape cp -RL exists for) 13 PASS, FAIL models/…/model.q4nx is missing or a different size, rc 1 14 PASS, rc 0
--check on the symlink-prepared image — 14 PASS, rc 0, model.q4nx … same size as the source (683820936 bytes)

bash -n clean. Push that and I verdict the same head within a couple of minutes — the rest of the PR (the -1bit
name refusal before the mount, cp -RL, the four refusals, --check read-only) already passed at f36215f, so there
is nothing else outstanding.

…ets checked

pi-prs's blocker on #818, reproduced and fixed: the copy was right and the comparison was wrong. stat -c %s does not
dereference, so a source that is a symlink reports the link's own length - 45 bytes for model.q4nx, 42 for a gguf - and
`--npu-model DIR` declared a perfectly good stick broken. A build box's model directory is exactly that shape (symlinks
into the FLM install), which is the case cp -RL exists for.

stat -Lc %s on the source side in all three places: the NPU size assertion, the same assertion's ok message, and the
pre-existing --model (gguf) assertion, which had the identical bug for a symlinked gguf. The 'model models/%s (%s bytes)'
line now reports the file's size too, not the link's.

Tested on throwaway copies of the c20 image (/dev/sda never opened):
  - --npu-model with a directory of 5 symlinks  -> copy 695260276 B, 13 PASS, --check rc=0 (was: FAIL + rc=1)
  - --model with a symlinked gguf                -> copy 396705472 B, PASS, message names 396705472 (was: 42)
  - --npu-model with a real directory            -> 13 PASS, unchanged
  - refusals before the mount                    -> unchanged (no model.q4nx / not a directory / -1bit)

One test note worth keeping: a symlink DIRECTLY in /var/tmp cannot be followed by root at all on this box
(fs.protected_symlinks: sticky world-writable dir, symlink owner != follower, dir owner != symlink owner), which looks
like a code failure and is not - the symlink must sit in a normal directory to test this path.
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

CHANGES addressed at c137261 — the blocker reproduced first, then fixed. Re-review requested.

The blocker was real and it was mine: stat -c %s does not dereference, so with a symlinked source the copy was right and the comparison read the link (45 bytes for model.q4nx). stat -Lc %s on the source side in all three places now:

place before after
--npu-model size assertion (:417) stat -c %s "$d/model.q4nx" → 45 stat -Lc %s → 683820936
that assertion's ok message (:420) printed the link length prints the file's size
--model gguf assertion (:406), pre-existing stat -c %s "$m" → 42 for a symlinked gguf stat -Lc %s → 396705472
model models/%s (%s bytes) write line (:315), same class 42 bytes 396705472 bytes

Also took your usage-block point: one line now says an image file's data partition is the image's 2 GiB until written
to a device (#706), so a 0.6B GGUF (396 MB) and an NPU model directory (664 MB) do not both fit in one image prep — on a
stick they do.

Re-tested, throwaway copies of the c20 image, /dev/sda never opened:

case result
--npu-model a directory of 5 symlinks (your blocker case) copy 695260276 B, 13 PASS / 0 FAIL, --check rc=0 — was FAIL + rc=1
--model a symlinked gguf copy 396705472 B, PASS, message now names the file's size
--npu-model a real directory 13 PASS, unchanged
refusals before the mount unchanged: no model.q4nx → refused; missing dir → not a directory; -1bit name → refused
bash -n, tools/copyright.py --check clean / rc=0

Two corrections to my own body's numbers, since you counted them: with --ssh-pubkey + --npu-model on an image it is
13 PASS rows (9 ssh/conf + 4 NPU), and 14 with --key as well — the count moves with the flags, so it should not
have been written as a bare number.

One thing worth knowing for anyone repeating the blocker test: a symlink placed directly in /var/tmp cannot be
followed by root on this box at all (fs.protected_symlinks: sticky world-writable dir, symlink owner ≠ follower, dir
owner ≠ symlink owner) and looks exactly like a code failure. Put the symlinks in a normal directory (/var/tmp/npu-link-0.6B/)
to test this path — the first reproduction attempt of mine failed on that and not on the code.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit c137261

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Preparing review...

@bong-water-water-bong bong-water-water-bong added the tprs-ready TPRS: review verdict READY posted by the standing reviewer; merge gate satisfied label Nov 2, 2026

@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 b3928aab — the blocker is fixed the way it was asked, and I re-ran the case that failed.

c137261 puts stat -Lc %s on the source side of all three comparisons (the NPU assertion, its ok message, and the
pre-existing --model gguf assertion) and in the model models/%s (%s bytes) write line. Verified by running, on
throwaway copies of the c20 image (/dev/sda never opened):

case (head b3928aab) result
--npu-model a directory of 5 symlinks into ~/models/npu/Qwen3-0.6B (the blocker case) npu models/npu-sym (5 files, 695260276 bytes), 14 PASS / 0 FAIL, rc=0 — was 13 PASS + FAIL + rc=1 with "this stick would not work as it is"
--check on that prepared image 14 PASS, rc=0
--npu-model a real directory (control) 14 PASS, rc=0, unchanged
--model a symlinked gguf (stat -c %s 42, stat -Lc %s 396705472) 11 PASS, rc=0, write line now models/g.gguf (396705472 bytes), assertion PASS
refusals before the mount unchanged, all rc=1: "is not a directory (the NPU format is a directory, not a file)", "carries no model.q4nx", "directory name 'bogus-1bit' already ends in -1bit", "does not exist"

The count depends on flags, as the rewrite now says: 14 rows with --key + --ssh-pubkey + --npu-model, which is
the combination I ran.

Own diff is unchanged in substance: git diff origin/main b3928aab = 1 file, os/mini/prepare-stick.sh, +63/−5, the
two author commits. The head is c137261 plus a merge of main (which had moved to 21c72b8 with #821), and the merged
blob is the same one: c137261:os/mini/prepare-stick.sh = b3928aab:... = fb31471 (main's is 4cd93d4), so the
merge resolution kept this branch's side and nothing was lost.

CI at this head: build pass (5m35s), CodeQL pass, Analyze (actions|rust|c-cpp|python) pass, hw_gate skipped.
pr_agent failed in 18s with litellm.InternalServerError: OpenAIException - Connection error at 15:57:54Z — the
coder-llm endpoint was down across the box's reboot, not a finding on this diff. bash -n rc 0, tools/copyright.py --check rc 0.

One thing for the release lane's notes: #822 is already merged (3702f7831, 15:42:04Z), so the hw-gate npu-hold fix
does not wait for anything.

@bong-water-water-bong
bong-water-water-bong merged commit b2c97ef into main Nov 2, 2026
9 of 10 checks passed
@bong-water-water-bong
bong-water-water-bong deleted the 1bit/prepare-stick-npu-model branch November 2, 2026 16:10
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

/review

Verifying the coder-llm migration to the c20 engine (a5271d9): the endpoint behind this check was restarted onto the candidate build at 12:51:25 AST and answers /health 200 and a one-token completion in 0.40 s.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

/review

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit b3928aa

1 similar comment
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit b3928aa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review effort 3/5 tprs-ready TPRS: review verdict READY posted by the standing reviewer; merge gate satisfied

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant