Skip to content

Move the wiki site generator to onnx-genai-wiki - #1488

Merged
justinchuby merged 1 commit into
mainfrom
justinchuby-wiki-move-site
Aug 20, 2026
Merged

justinchuby merged 1 commit into
mainfrom
justinchuby-wiki-move-site

Conversation

@justinchuby

Copy link
Copy Markdown
Owner

The wiki site is now published from justinchuby/onnx-genai-wiki, so the static site generator comes out of this repository.

What moves

site/ (Quartz, its plugin lockfiles, the build and validation scripts) and .github/workflows/wiki-pages.yml. All of it is now in the publishing repository, unchanged except for what the move required.

What stays

wiki/ — the notes themselves. This repository remains the source of truth for them, and they are still edited only here.

How publishing works now

onnx-genai/wiki/  ──sync──▶  onnx-genai-wiki/content/zh/  ──translate──▶  content/en/
   (source of truth)              (mirror)                                 (derived)

A scheduled workflow in the publishing repository mirrors wiki/ into content/zh/ and writes a manifest of this repository's tracked paths so links into crates/ and docs/ can still be resolved and checked without a checkout. An English edition is derived from the Chinese pages, and both are published at /zh/ and /en/ with a language switcher.

The mirror is replaced wholesale on each sync, so a page deleted here disappears there. The consequence is worth stating plainly, and it is recorded in both wiki/README.md and the wiki maintenance note: an edit made directly to the mirror is silently overwritten.

The site is at https://www.justinchuby.com/onnx-genai-wiki/.

Why a sync rather than a submodule

Measured, not assumed: this repository's .git is about 229 MB and wiki/ is about 212 KB. A submodule would clone all of it on every build to reach a thousandth of it, and could only reference the whole repository rather than one directory. Copying also gives content/zh a real commit history in the publishing repository, which is what the translation staleness check reads.

Other changes here

  • .gitignore loses the site/quartz build-state entries.
  • ci.yml no longer counts site/* as documentation-only. A path filter for a directory that cannot exist reads as intent to whoever changes it next.

Checked

Wikilink validation passes on wiki/ — 145 links across 25 notes — using the validator that moved with the generator. The publishing repository builds both languages from these exact pages: 4159 links across 146 pages per locale, identical page sets in the two editions, and every note carrying the lang from its frontmatter.

One defect turned up in that build and is worth knowing about, because no check of the Markdown could have found it. Obsidian reads #word as an inline tag when it follows whitespace. The Chinese text writes 、#864/#874(WDDM 回退), where the ideographic comma stops it being a tag; the natural English rendering is , #864/#874 (WDDM fallback), which produced a tag page called 864/874 in the English site and nowhere else. The publishing build now requires both locales to emit the same set of pages, since every page derives from something identical across the two trees.

The site is now published from justinchuby/onnx-genai-wiki, which mirrors this
directory and derives an English edition from it, so readers get a bilingual
site with a language switcher. This repository keeps what it was already the
authority for — the notes themselves — and stops carrying a static site
generator, its plugin lockfiles and its Node dependency tree, none of which
have anything to do with the runtime.

wiki/ stays the source of truth. Notes are still edited only here; the sync is
one-directional, and the mirror is replaced wholesale on each run so that a
page deleted here disappears there too. The corresponding warning is recorded
in both wiki/README.md and the wiki maintenance note: an edit made directly to
the mirror will be silently overwritten, which is the failure mode most likely
to waste someone's afternoon.

ci.yml no longer counts site/ as documentation-only. Leaving it would keep a
path filter alive for a directory that cannot exist, and a stale filter that
matches nothing reads as intent to someone changing it later.

Wikilink validation still passes here — 145 links across 25 notes — using the
validator that moved with the generator; the publishing repository runs it
again on the mirror, and additionally requires the Chinese and English
editions to emit exactly the same set of pages.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c80f8522-983c-47f7-8241-2155a823aabe
@justinchuby
justinchuby merged commit b71ac4a into main Aug 20, 2026
7 of 15 checks passed
@justinchuby
justinchuby deleted the justinchuby-wiki-move-site branch August 20, 2026 00:14
@github-actions

Copy link
Copy Markdown

🔴 Benchmark Regression Detected

Comparison of criterion micro-benchmarks: PR head vs merge-base, measured on the same runner in the same job (base first → PR second).

ℹ️ Absolute times are informational only — they vary with runner load. The % change column is the reliable signal because both sides ran under identical conditions.

Status Scenario Base PR Change
🔴 block_quantized_matmul_cached_dense/mxfp4_cached_dense_repeated_call/1x1024x1024 43.23 µs 123.95 µs +186.7%
🔴 block_quantized_moe_cached_dense/mxfp4_uncached_expert_dequant_each_call/rows=1,H=256,I=256,E=4,top_k=1 359.39 µs 572.43 µs +59.3%
🔴 matmul/medium_generic_bf16_threads=8/32x512x512 373.38 µs 588.11 µs +57.5%
🔴 matmul/large_generic_bf16_threads=8/32x1024x1024 1.32 ms 2.03 ms +53.8%
🔴 qwen3_sampling_processors/top_k_top_p_full_sort_baseline 5.27 ms 8.04 ms +52.7%
🔴 sampling_latency/top_k_per_token 48.58 µs 69.34 µs +42.7%
🔴 block_quantized_matmul_cached_dense/mxfp4_preexpanded_dense_oncelock_like_proxy/1x1024x1024 50.61 µs 71.62 µs +41.5%
🔴 block_quantized_moe_cached_dense/mxfp4_cached_dense_expert_repeated_call/rows=1,H=256,I=256,E=4,top_k=1 52.69 µs 72.58 µs +37.8%
🔴 matmul/large_generic_bf16_threads=1/32x1024x1024 2.15 ms 2.83 ms +31.7%
🔴 tokenization/decode_tokens_per_second 5.81 ms 7.63 ms +31.2%
⚠️ gather/medium_f32_threads=1-internal/32768 4.12 µs 5.25 µs +27.6%
⚠️ grammar_masking/llguidance_compute_mask/32 72.56 µs 91.96 µs +26.7%
⚠️ qwen3_sampling_processors/top_p_full_sort_after_top_k_baseline 3.27 ms 4.14 ms +26.3%
⚠️ matmul/medium_generic_f16_threads=8/32x512x512 37.07 µs 45.29 µs +22.2%
⚠️ matmul/large_generic_f16_threads=8/32x1024x1024 91.06 µs 110.40 µs +21.2%
⚠️ sampling_latency/greedy_per_token 3.02 µs 3.67 µs +21.2%
⚠️ gather/small_f16_threads=1-internal/4096 494.9 ns 596.7 ns +20.6%
⚠️ matmul/large_generic_f16_threads=1/32x1024x1024 78.46 µs 94.07 µs +19.9%
⚠️ kv_cache/alloc_dealloc_pages 36.45 µs 43.64 µs +19.7%
⚠️ sampling_latency/top_p_per_token 389.28 µs 461.09 µs +18.4%
⚠️ block_quantized_matmul_cached_dense/mxfp4_uncached_dequant_each_call/1x1024x1024 567.90 µs 665.64 µs +17.2%
⚠️ matmul/medium_generic_bf16_threads=1/32x512x512 527.42 µs 618.06 µs +17.2%
⚠️ qwen3_sampling_processors/top_k_full_sort_baseline 1.96 ms 2.27 ms +15.8%
⚠️ matmul/small_generic_f32_threads=1/1x256x256 39.23 µs 45.27 µs +15.4%
✅ matmul/medium_generic_f16_threads=1/32x512x512 37.09 µs 42.56 µs +14.8%
✅ qwen3_sampling_processors/top_k_top_p_fast 633.04 µs 719.63 µs +13.7%
✅ gather/small_bf16_threads=1-internal/4096 485.1 ns 548.2 ns +13.0%
✅ gather/large_bf16_threads=1-internal/131072 15.78 µs 17.82 µs +13.0%
✅ qwen3_sampling_processors/top_p_fast_after_top_k 498.86 µs 562.33 µs +12.7%
✅ sampling_latency/min_p_per_token 194.57 µs 217.33 µs +11.7%
✅ matmul/small_generic_bf16_threads=8/1x256x256 41.77 µs 46.59 µs +11.5%
✅ tokenization/encode_tokens_per_second 353.08 µs 389.76 µs +10.4%
✅ gather/large_f32_threads=1-internal/131072 39.58 µs 43.59 µs +10.1%
✅ gather/medium_f16_threads=1-internal/32768 2.80 µs 3.04 µs +8.7%
✅ matmul/large_generic_f32_threads=1/32x1024x1024 10.08 ms 10.85 ms +7.6%
✅ gather/medium_bf16_threads=1-internal/32768 2.81 µs 3.00 µs +6.9%
✅ qwen3_sampling_processors/top_k_partial_selection 133.80 µs 142.53 µs +6.5%
✅ matmul/medium_generic_f32_threads=8/32x512x512 1.24 ms 1.32 ms +6.5%
✅ matmul/large_generic_f32_threads=8/32x1024x1024 4.25 ms 4.51 ms +6.0%
✅ logit_processing/seven_processor_chain_per_step 352.68 µs 367.36 µs +4.2%
✅ gather/small_f32_threads=1-internal/4096 752.3 ns 773.3 ns +2.8%
✅ gather/large_f16_threads=1-internal/131072 15.42 µs 15.75 µs +2.1%
✅ matmul/medium_generic_f32_threads=1/32x512x512 2.50 ms 2.54 ms +1.8%
✅ matmul/small_generic_f16_threads=8/1x256x256 43.97 µs 43.98 µs +0.0%
✅ matmul/small_generic_bf16_threads=1/1x256x256 49.51 µs 48.97 µs -1.1%
✅ matmul/small_generic_f16_threads=1/1x256x256 36.77 µs 36.07 µs -1.9%
✅ add/large_bf16_threads=1-internal/4194304 1.96 ms 1.85 ms -5.9%
✅ reduce_mean/medium_f32_threads=1-internal/65536 307.36 µs 286.04 µs -6.9%
✅ add/medium_f16_threads=1-internal/262144 141.76 µs 130.53 µs -7.9%
✅ reduce_mean/small_f32_threads=1-internal/4096 17.81 µs 16.35 µs -8.2%
🟢 reduce_mean/large_f32_threads=1-internal/262144 1.25 ms 1.04 ms -16.2%
🟢 add/medium_bf16_threads=1-internal/262144 155.15 µs 124.71 µs -19.6%
🟢 add/large_f32_threads=1-internal/4194304 1.16 ms 902.54 µs -22.1%
🟢 matmul/small_generic_f32_threads=8/1x256x256 62.18 µs 47.02 µs -24.4%
🟢 add/large_f16_threads=1-internal/4194304 2.76 ms 1.99 ms -28.0%
🟢 add/small_bf16_threads=1-internal/1024 767.4 ns 549.0 ns -28.5%
🟢 add/small_f32_threads=1-internal/1024 321.5 ns 186.8 ns -41.9%
🟢 add/medium_f32_threads=1-internal/262144 52.19 µs 30.21 µs -42.1%
🟢 add/small_f16_threads=1-internal/1024 785.4 ns 436.3 ns -44.4%

Visual flags: ⚠️ ≥ 15% slower, 🔴 ≥ 30% slower — calibrated against measured runner noise (~27% worst-case on multi-threaded matmul)

Host info
CPU: Apple M1 (Virtual)
Cores: 3
OS: Darwin 25.5.0 arm64
Rust: rustc 1.97.1 (8bab26f4f 2026-07-14)
Load avg: { 4.16 3.79 6.78 }
What this cannot catch
  • Regressions in code paths not covered by these benchmarks (e.g., end-to-end decode with a real model)
  • Sub-threshold regressions that compound over multiple PRs
  • Performance changes that only manifest under GPU execution
  • Latency changes in the ORT integration path (these benchmarks exercise the native Rust kernels)

@codecov

codecov Bot commented Aug 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.12%. Comparing base (4a9f4ec) to head (b31e363).
⚠️ Report is 67 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #1488       +/-   ##
===========================================
- Coverage   82.10%   80.12%    -1.99%     
===========================================
  Files          12      376      +364     
  Lines        5471   164127   +158656     
  Branches     5471   164127   +158656     
===========================================
+ Hits         4492   131507   +127015     
- Misses        780    27793    +27013     
- Partials      199     4827     +4628     
Flag Coverage Δ
cli-ort-linux 82.60% <ø> (?)
cli-ort-windows 82.10% <ø> (ø)
offline 80.03% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 365 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

justinchuby added a commit that referenced this pull request Aug 25, 2026
…2052)

Follow-up to #2036, merged earlier today. **The guard it shipped cannot
see a stray *directory* at the root — and two of the seven historical
instances are directories, one of them cited in #2036's own header.**

## The gap

#2036 compares tracked files whose path contains no separator:

```bash
git ls-files | grep -v '/'
```

A stray directory has no such path. `.commitmsg/m.txt` contains a
separator, so it is discarded as "not at the root" — and the thing that
*is* at the root, `.commitmsg`, never appears in `ls-files` output at
all. The guard doesn't fail to complain; it affirmatively reports a
clean root.

Not hypothetical: `.commitmsg/` reached `main` as `faedea4d1`, removed
three minutes later by `490b846c3` *"Remove accidentally tracked PR
artifacts"*. #2036's header lists it, with the trailing slash. **I
enumerated the instance and then validated against six arms that all
used a file.** Naming an instance is not testing its shape.

## The fix

Compare **first path segments** — a root file contributes itself, a
nested file contributes its top-level directory:

```bash
git -c core.quotePath=false ls-files | sed 's#/.*##' | LC_ALL=C sort -u
```

The allowlist gains the 20 tracked root directories (36 entries), and
unlisted entries are labelled `(directory)` or `(symlink)` where they
are one, because the remedy differs.

## The inventory, corrected by review

I claimed six instances "found by walking every root path ever added,
not by collecting what people reported". **The walk had the same blind
spot as the guard** — it filtered to paths without a separator, so it
could not see a stray directory either. Redone on first segments:

| entry | added → removed | on `main` |
|---|---|---|
| `.msg.txt` | `39675330b` → `bbc193117` | 1.6h |
| **`.commitmsg/`** | `faedea4d1` → `490b846c3` | 3m |
| **`.goldens/`** | `faedea4d1` → `490b846c3` | 3m |
| `.wa64.log` | `83a51bfa6` → `c07acaa78` | 17.2h |
| `.commitmsg` | `e42fa9470` (#1881) → `398cff8e5` (#1999) | 19.8h |
| `.pris_v4.log` | `589d48ffd` (#1951) → `7a6482c83` (#1975) | 1.3h |
| `.body.md` | `79196f89d` (#2026) → `54625db9d` (#2036) | 2.7h |

**Seven entries, six incidents** — `.commitmsg/` and `.goldens/` arrived
and left together. `.goldens/` is the most on-point instance available
(a directory removed as a "PR artifact") and my method could not see it.

Excluded, with reasons recorded in the file rather than silently: `site`
(moved to onnx-genai-wiki, #1488), `third_party` (oneDNN removal), and
`abresults` — 131h on `main`, the longest of any, but added by a
`docs(benchmarks): record the … result` commit that says it is recording
a result. Intentional-when-added is the line; `.wa64.log` rode in on a
`test(cpu):` commit that never mentions it.

`.wa64.log` still matters beyond the count: it predates `.pris_v4.log`
by two days, so `/*.log` in #1975 was reactive to the *second* log
incident.

No authorship attributed — squash-merge rewrites `%an` to the merging
account, so it reads identically for all seven and says nothing about
who staged the file.

## Validation — 15/15

Driving the script **extracted from the workflow YAML**, never a copy.

| arm | rc |
|---|---|
| clean root | 0 — `Root is exactly the 36 allowlisted entr(ies).` |
| **stray root directory → new guard** | **1**, labelled `(directory)` |
| **same stray → #2036 guard + #2036 allowlist** | **0** — `Root is
exactly the 16 allowlisted file(s).` |
| `.goldens/`, the second directory instance | 1 |
| duplicate allowlist entry → not reported stale | 0, warning names it |
| root symlink | 1, labelled `(symlink)` |
| stray root file / stale entry / comments-only / missing list | 1 / 1 /
1 / 1 |
| nested file under an allowlisted dir | 0 |
| non-ASCII root file, allowlisted | 0 |
| new root directory allowlisted in-PR / not | 0 / 1 |
| CRLF allowlist | 0 |

Row 3 is the control and must pair **both** of #2036's halves. My first
attempt paired the old guard with the *new* allowlist: it returned 1 and
looked like coverage, but the 1 came from 20 directory entries reading
as stale.

## Two instrument bugs in my own battery

1. **Wrong control**, above — a control that changes two things measures
neither.
2. **The staging check had the defect the guard was fixed for.** Each
arm asserts its input reached the index before believing the output, but
that check used bare `git diff --cached --name-only`, which renders
non-ASCII as `"caf\303\251.txt"` while the guard uses
`core.quotePath=false`. It reported the non-ASCII arm VACUOUS against a
setup that had worked. Opus caught exactly this in #2036's guard; it
reappeared in the thing measuring the guard.

## Also fixed, from review

- An entry listed twice left one copy unpaired in `comm` and was
reported as "not present at the root" for a name that is. Deduped both
sides; duplicates now raise a `::warning::` naming them.
- `[ -d ]` follows symlinks, so a root symlink to a directory was
labelled a directory and advised `git rm -r --cached`. `-L` tested
first.
- Recorded the cost of first-segment comparison: the guard sees **root
children only**. Scratch under an already-blessed directory is invisible
to it.

## Scope

CI-config only — `.github/workflows/diff-guard.yml` and
`.github/root-file-allowlist.txt`. No Rust, no runtime behaviour, no
test changes. Adding a root entry, file or directory, means adding it to
the allowlist in the same PR; the error message says so.

---------

Co-authored-by: holden <holden@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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