Skip to content

Pin the C++ span names to the ladder, and stop writing them twice - #1909

Merged
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
ChaoWao:pin-cpp-span-names-to-the-ladder
Aug 20, 2026
Merged

Pin the C++ span names to the ladder, and stop writing them twice#1909
ChaoWao merged 1 commit into
hw-native-sys:mainfrom
ChaoWao:pin-cpp-span-names-to-the-ladder

Conversation

@ChaoWao

@ChaoWao ChaoWao commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Why

Reviewing #1875 turned up how a rename can go wrong silently. That PR adds

EXPECT_FALSE(captured_host_span("host.dispatch"));

on a base predating #1893, where the word became node. Rebasing produces no conflict — the line is new, not edited — so the assertion looks for a name nothing emits, captured_host_span answers false, and EXPECT_FALSE(false) passes. The test that exists to prove a disabled gate emits nothing would pass whether the gate works or not.

Ranked by when you find out, that is the worst of the three outcomes a rename can have:

Outcome Found
conflict immediately
red test one CI run
vacuously-true assertion never

What makes it silent is the negated form — the same staleness under EXPECT_TRUE merely goes red.

What this changes

Two things, and the first is not a new guard but removal of what made a guard necessary.

1. The names come from the table the emitter uses. Eight literals in test_scheduler.cpp become host_span_name(HostSpan::Dispatch) and friends. Those tests assert that a decision point emitted at all — the name is not their subject, so spelling it out was a second copy of it.

2. The C++ pre-bind default is pinned to the ladder. host_span_names.h's level_word() defaults to "node", which was a third hand-written copy of the L3 word:

Copy Pinned by
WorkerLevel (source of truth)
strace_timing.py::_NODE_WORDS ✅ its own test (#1886)
host_span_names.h::level_word() default nothing

A level renamed in Python would leave C++ emitting the old word for every span emitted before a Worker binds the prefix, and no test would notice.

The pin reads that default through the existing binding rather than adding a symbol: set_level_prefix("") returns early without binding, while the binding still reports what is in effect. It runs in a child process because the prefix freezes on first bind — a Worker constructed anywhere in this process would leave the bound word behind instead of the default.

test_graph_failure_still_emits_graph_build_span also spelled out node.graph_build; it now builds the expected name from the worker's own _host_span_prefix, which is the contract that assertion is actually about.

Not every literal is a double-write

The distinction is which side of the test it sits on, and it is the reusable part of this change:

  • A literal that constructs input — the SimplerHostSpan fed to the logger in test_host_log_off.cpp, the fake log lines in test_strace_timing.py — is right to be written out. The test owns its input and is exercising encoding or parsing over an arbitrary name.
  • A literal that asserts the implementation emitted a particular name is the second copy. The eight in test_scheduler.cpp were the only ones of that kind.

Testing

  • pytest tests/ut/py1657 passed, 0 failed
  • ctest -LE requires_hardware107/107
  • Negative control for the pin — setting the C++ default back to "host" fails test_the_cpp_pre_bind_level_word_is_the_ladder_word_for_l3 and nothing else
  • Negative control for the double-write removal — renaming the level word to network9 keeps test_scheduler green, because the assertions follow. Under the old literals the same rename would have reddened the EXPECT_TRUE ones and silently passed an EXPECT_FALSE one.

Scope

Stated because "renames are guarded now" would be too broad: the pin ties the C++ default word to the ladder, not every place a name could be spelled out. git grep -n '"\(node\|network[123]\)\.' before landing a rename, and judge each hit by the input-versus-assertion test above.

Found while reviewing #1875 (#1792 items 3 and 7); that PR still needs a rebase, after which its own assertion should use the same accessor.

Reviewing hw-native-sys#1875 turned up how a rename can go silently wrong. That PR adds

    EXPECT_FALSE(captured_host_span("host.dispatch"));

on a base that predates hw-native-sys#1893, where the word became `node`. Rebasing produces no
conflict — the line is new, not edited — so the assertion looks for a name nothing
emits, `captured_host_span` answers false, and `EXPECT_FALSE(false)` **passes**.
The test that exists to prove a disabled gate emits nothing would then pass
whether the gate works or not.

Ranked by when you find out, that is the worst of the three outcomes a rename can
have: a conflict is immediate, a red test is one CI run, and a vacuously-true
assertion is never. What makes it silent is the negated form — the same staleness
under `EXPECT_TRUE` merely goes red.

Two changes, and the first is not a new guard but the removal of what made the
guard necessary.

**The names come from the table the emitter uses.** Eight literals in
`test_scheduler.cpp` are now `host_span_name(HostSpan::Dispatch)` and friends.
These tests assert that a decision point emitted at all; the name is not their
subject, so writing it out was a second copy of it. Taking it from the single
source means a rename cannot leave them behind — verified by renaming the level
word to `network9` and re-running: the suite stays green because the assertions
follow. Under the old literals the same rename would have reddened the
`EXPECT_TRUE` ones and silently passed an `EXPECT_FALSE` one.

**The C++ pre-bind default is pinned to the ladder.** `host_span_names.h`'s
`level_word()` defaults to `"node"`, which was a third hand-written copy of the L3
word: `WorkerLevel` is the source of truth, `strace_timing.py`'s `_NODE_WORDS` is
pinned to it by its own test, and this one was pinned to nothing. A level renamed
in Python would leave C++ emitting the old word for every span before a Worker
binds the prefix, with no test noticing.

The pin reads that default through the existing binding rather than adding a
symbol: `set_level_prefix("")` returns early without binding, while the binding
still reports what is in effect. It runs in a child process because the prefix
freezes on first bind, so a Worker constructed anywhere in this process would
leave the *bound* word behind instead of the default.

`test_graph_failure_still_emits_graph_build_span` also spelled out
`node.graph_build`; it now builds the expected name from the worker's own
`_host_span_prefix`, which is the contract that assertion is about.

Verification:

- `pytest tests/ut/py` — 1657 passed, 0 failed.
- `ctest -LE requires_hardware` — 107/107.
- Negative control for the pin: setting the C++ default back to `"host"` fails
  `test_the_cpp_pre_bind_level_word_is_the_ladder_word_for_l3` and nothing else.
- Negative control for the double-write removal: renaming the level word to
  `network9` keeps `test_scheduler` green, where a literal would have gone red or,
  worse, vacuously true.

Not every literal span name is a double-write, and the distinction is which side
of the test it sits on. A literal that **constructs input** — the
`SimplerHostSpan` fed to the logger in `test_host_log_off.cpp`, the fake log lines
in `test_strace_timing.py` — is right to be written out: the test owns its input,
and it is exercising encoding or parsing over an arbitrary name. A literal that
**asserts the implementation emitted a particular name** is the second copy, and
that is the class both changes above remove. The eight in `test_scheduler.cpp`
were the only ones of that kind.

What this does not cover, stated because "renames are guarded now" would be too
broad a claim: the pin ties the C++ *default* word to the ladder, not every place
a name could be spelled out. `git grep -n '"\(node\|network[123]\)\.'` before
landing a rename, and judge each hit by the input-versus-assertion test above.
@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@ChaoWao, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 39 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a2b90c8c-d018-4411-91d1-42fd5e633286

📥 Commits

Reviewing files that changed from the base of the PR and between d1eb826 and 1ee6e07.

📒 Files selected for processing (2)
  • tests/ut/cpp/hierarchical/test_scheduler.cpp
  • tests/ut/py/test_worker/test_host_worker.py

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.

@ChaoWao
ChaoWao merged commit 9e2b4db into hw-native-sys:main Aug 20, 2026
28 of 29 checks passed
@ChaoWao
ChaoWao deleted the pin-cpp-span-names-to-the-ladder branch August 20, 2026 06:21
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