---
"@ux-team/tvu-design-system": patch
---

Widen the §M23.8.1 source-link scope by one level — from "the source marker is in the same
TEXT node" to "a sibling in the same immediate parent carries it".

**Why.** A PRD card's `Source` section stores its heading (`Source 需求来源`) in one TEXT
node and each reference on a *separate sibling* node. Those sibling nodes contain no source
marker of their own, so under the old scope all 8 ticket / Slack references in that section
fell outside the denominator and `source-link-integrity` reported `checkedUnits=0` — a green
that means "nothing to judge", not "judged and clean". The owner spotted the problem by eye
(every link rendered in the body colour with no underline) while the gate was green.

- `collectSourceTickets` / `classifySourceLinkIntegrity` now take sibling context into
  account and expose a new `inScopeBySiblingCount` counter, kept separate from
  `markedTextCount` (which still counts only self-matches).
- **Scope widens by exactly one level, deliberately.** Propagating further down the tree
  approaches "judge every ticket-shaped range", which was measured and rejected on
  2026-09-08: the 82 out-of-scope ranges include false positives that cannot be excluded by
  shape (`Q2-1` is a design-exploration question number, `PID-1001` comes verbatim from
  product UI copy `Stop preview for PID-1001?`), and prefix filtering cannot separate them
  either because real project keys like `V4` and `TM3` contain digits themselves.
- **Known cost, recorded honestly.** If a product term (`Source Switcher`, TVU's first-class
  term for a signal source) happens to share an immediate parent with a ticket, that ticket
  is pulled into the denominator. On the real surface the two sit in different frames
  (product frame vs delivery card), so no instance has been observed; a unit test pins the
  shape so it is not silently forgotten.
- **Readings are not re-measured.** The `23 / 82 / 3 / 4 / 16` figures in the criterion's
  header comment are all *pre-widening*; the payload snapshots are not in git. Re-measure
  with `pnpm audit:mockup-conformance --file <key>` (whole-file, no `--node`) and read
  `checkedUnits`.

Regression face: 3 new cases cover the new path (positive / negative control / known false
positive). Removing `|| siblingMarked` turns exactly those 3 red and leaves the other 23
green — the F-T1 control and the "one level only" boundary pass under both implementations,
so they guard the boundary rather than the new behaviour.

The A-probe hint now states the full fix: the linked range must carry cyan `#33A4FD` **and**
`UNDERLINE`. Per-rule visual-cue checking is not yet a criterion (no baseline measured); the
rule text is the source of truth for it.
