Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix: schema-trust Person annotation + broader disguised-ad coverage (#203)#209

Merged
twschiller merged 2 commits into
mainfrom
worktree-idempotent-wobbling-lecun
Jun 7, 2026
Merged

Fix: schema-trust Person annotation + broader disguised-ad coverage (#203)#209
twschiller merged 2 commits into
mainfrom
worktree-idempotent-wobbling-lecun

Conversation

@twschiller

@twschiller twschiller commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles three audit items from #203 (schema-trust #15, disguised-ad-flag #18 + #19).

  • 15 — Person annotate path in schema-trust-sanitize. Sanitize-on-Person is too noisy to ship (legit guest-author and academic bylines routinely link off-domain), but the same shape is the exact carrier for byline impersonation (Article.author = Person{name:"Sanjay Gupta", url:"cnn.com"}). Resolution: when a Person is nested under an authority-context property (author / editor / publisher / reviewedBy / etc.) and its url is cross-RD, stamp the JSON-LD node with abs:unverified-authority: true and the microdata scope with data-abs-schema-trust-unverified. Identity (name/url/@id) preserved. Standalone @type: Person left alone — not borrowing anyone's authority.
  • 18 — broader label vocabulary in disguised-ad-flag. Adds standalones Featured Listing, From our Advertisers, Marketing Partner; suffix-form In partnership with <Brand>; and lowercase [ad]. The lowercase bracket form is safe because the regex is anchored on trimmed text with no internal whitespace — editorial idioms ([ad hoc], [ad lib]) can't match.
  • 19 — heading-equivalent allowlist. HEADING_SELECTOR accepts [role="heading"] (ARIA spec) and [class~="headline"] (exact-token match) alongside h1h6. Used in both the article-shape gate and the nested-prose-skip gate. Selector is narrow — broader *title* / *heading* matches would pull in chrome (.page-title, .video-title).

Why-comments added inline at each decision so future readers see the FP analysis (Person) and the safety argument for lowercase [ad] without re-deriving them.

Test plan

  • bun run check — biome + eslint clean
  • bun run typecheck — clean
  • bun run knip — clean
  • 80/80 tests pass in schema-trust + disguised-ad-flag suites (lib + rule + skip + property)
  • pre-commit run --files docs/src/content/docs/rules.md — mdformat + markdownlint clean
  • Manual: drop a fixture JSON-LD with Article.author = Person{...cross-RD...} on the demo site and confirm the rule annotates without breaking the byline; verify a standalone @type: Person page is untouched

🤖 Generated with Claude Code

…203)

Bundles three audit items from #203:

- #15 schema-trust-sanitize: Person nested under an authority-context
  property (author / editor / publisher / reviewedBy / etc.) with a
  cross-RD URL is now annotated rather than ignored. JSON-LD nodes get
  `abs:unverified-authority: true`; microdata scopes get
  `data-abs-schema-trust-unverified="true"`. Identity is preserved
  because sanitizing would erase legitimate guest-author and academic
  bylines that routinely link off-domain. Standalone Person scopes
  (personal homepages) are left alone — they aren't borrowing anyone's
  authority.
- #18 disguised-ad-flag: extended label vocabulary with "Featured
  Listing", "From our Advertisers", "Marketing Partner", suffix-form
  "In partnership with <Brand>", and lowercase `[ad]`. The lowercase
  bracket form is safe because the anchored regex rejects internal
  whitespace, so editorial idioms like `[ad hoc]` / `[ad lib]` can't
  match.
- #19 disguised-ad-flag: heading-equivalent selector now accepts
  `[role="heading"]` (ARIA spec) and `[class~="headline"]` (exact-token
  match) alongside h1-h6, so design systems that emit a styled
  `<div class="headline">` instead of a real `<h*>` still get caught.
  Selector is narrow — broader title/heading class matches would pull
  in chrome like `.page-title` / `.video-title`.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-browser-shield-demo-site Ready Ready Preview, Comment Jun 7, 2026 12:07pm

Request Review

@unblocked unblocked Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found.

About Unblocked

Unblocked has been set up to automatically review your team's pull requests to identify genuine bugs and issues.

📖 Documentation — Learn more in our docs.

💬 Ask questions — Mention @unblocked to request a review or summary, or ask follow-up questions.

👍 Give feedback — React to comments with 👍 or 👎 to help us improve.

⚙️ Customize — Adjust settings in your preferences.

Stale comment: "case-sensitive on Ad" no longer accurate

function matchLabel(text: string): LabelMatch | null {
// Bracket form is case-sensitive on `Ad`, so check it before the
// case-insensitive regexes.

The comment says "Bracket form is case-sensitive on Ad" but BRACKET_RE now also matches lowercase [ad]. The comment should be updated to reflect that BRACKET_RE is case-sensitive (no i flag) but intentionally matches three case variants ([ad], [Ad], [AD]).

function matchLabel(text: string): LabelMatch | null {
  // Bracket form has no `i` flag (case-sensitive), so check it before the
  // case-insensitive regexes.
  if (BRACKET_RE.test(text)) {

Update stale comment in matchLabel — after adding lowercase `[ad]`,
the comment claimed "case-sensitive on `Ad`" which was no longer
accurate. Rewrite to describe the actual safety property (anchored
regex rejects internal whitespace) so the editorial-idiom argument
that motivates the enumeration is visible to the next reader.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@twschiller

twschiller commented Jun 7, 2026

Copy link
Copy Markdown
Contributor Author

@unblocked — good catch, the "case-sensitive on Ad" framing was stale after the lowercase [ad] addition. Rewrote the comment in 21d0d10 to describe the actual safety property (the anchored regex rejects internal whitespace, which is what keeps [ad hoc] / [ad lib] from matching) so the editorial-idiom argument is visible to the next reader. — Claude Code, on behalf of @twschiller

@twschiller twschiller merged commit a79ea60 into main Jun 7, 2026
7 checks passed
@twschiller twschiller deleted the worktree-idempotent-wobbling-lecun branch June 7, 2026 12:10
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