Skip to content

feat(adp): citation-bait schema fields + FAQPage emission#397

Merged
mergify[bot] merged 4 commits into
mainfrom
feat/adp-citation-schema-fields
May 17, 2026
Merged

feat(adp): citation-bait schema fields + FAQPage emission#397
mergify[bot] merged 4 commits into
mainfrom
feat/adp-citation-schema-fields

Conversation

@julianken
Copy link
Copy Markdown
Owner

Summary

Adds three optional citation-bait fields to the Pattern type, renders them visibly on satellite pages, and emits FAQPage JSON-LD when relatedQuestions is populated. Also adds a dedicatedDateModified field to Posts to replace the over-firing updatedAt as the BlogPosting.dateModified signal.

Changes

Pattern type + render

  • relatedQuestions?: { q, a }[] rendered as visible <dl> Q&A block via new RelatedQuestionsBlock component (NOT in DisclosureSection — FAQPage rich result eligibility requires visible content).
  • keyStatistic?: { claim, sourceUrl, year } rendered as above-fold callout via KeyStatisticCallout.
  • expertQuote?: { text, attribution, sourceUrl } rendered as <blockquote> via ExpertQuoteBlock.

Schema

  • New generateFaqPageSchema emits FAQPage as a second top-level JSON-LD block (per Google rich-result guidance) when relatedQuestions is populated. Null otherwise.
  • generateBlogPostingSchema now uses post.dedicatedDateModified ?? post.updatedAt (resolves the TODO at blog-posting.ts:63-70).

Posts collection

  • New optional dedicatedDateModified date field (sidebar, day-and-time picker).
  • New beforeChange hook updates it only when body, title, or summary actually changed (not every save). Editor-supplied values are preserved.

Test plan

  • Unit tests for generateFaqPageSchema — null when empty/absent, valid shape when populated (12 new tests; existing 537 pass unchanged for total 537->549)
  • pnpm payload generate:types clean — dedicatedDateModified?: string | null lands on Post type
  • pnpm lint (incl. lint:adp) — 0 errors, typecheck-sketches/validate-references/check-affiliate-links/lint-changelog all pass
  • pnpm test:unit — 549/549 pass
  • pnpm typecheck — clean
  • Local smoke: temporarily added relatedQuestions: [{ q: "Smoke test?", a: "Smoke test answer." }] to reflexion.ts, verified rendered HTML contains "@type":"FAQPage" as the 3rd top-level JSON-LD schema and a visible Common questions Q&A block; reverted before commit.
  • CI (4 E2E shards + bundle + build will run)

Out of scope (deliberately deferred)

  • Populating relatedQuestions / keyStatistic / expertQuote for any pattern — that's Julian's writing time (Category I in the SEO plan).

Closes #389

Add three optional Pattern fields (relatedQuestions, keyStatistic, expertQuote)
and a dedicatedDateModified field on Posts. Render the three Pattern fields
as visible (not collapsed) callouts/blockquote/Q&A on satellite pages.
Emit FAQPage JSON-LD when relatedQuestions is populated.

The Posts dedicatedDateModified field is set by a beforeChange hook only
when body/title/summary changes, replacing the over-firing updatedAt as
the dateModified signal in BlogPosting schema.

This PR ships template infrastructure only -- no pattern data files are
populated with the new fields.

Closes #389
@julianken julianken added agentic-design-patterns Agentic Design Patterns reference page work status:in-review PR open, waiting for review area:seo SEO + AI-discovery strategy work labels May 17, 2026
Copy link
Copy Markdown
Collaborator

@julianken-bot julianken-bot left a comment

Choose a reason for hiding this comment

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

Verdict — REQUEST_CHANGES

Verification ledger

  • pnpm test:unit → 32 files, 537 tests, all pass (baseline at 51369a1 was 31 files, 525 tests; this PR adds the new faq-page.test.ts file with 12 tests, matching the delta the description claims structurally even though the absolute numbers in the description ("537 → 549") appear miscounted against the actual baseline of 525).
  • pnpm typecheck → clean.
  • pnpm lint → 0 errors on tracked files. The 1435 errors reported locally are all under .claude/worktrees/ (untracked Next.js build artifacts polluting local eslint scan); does not block this PR.
  • gh pr view ... mergeableMERGEABLE, not draft.
  • R15 mermaid render check → no fenced blocks in PR body; trivially passes.

Findings

# Severity File:line Summary
1 IMPORTANT src/lib/hooks/before-change-dedicated-date-modified.ts:36 editorSetField misreads Payload data partial: hook auto-stamps once, then never again on subsequent content edits. Defeats the PR-stated purpose.
2 SUGGESTION src/lib/hooks/before-change-dedicated-date-modified.ts:54 No unit tests for the new hook; the 12 new tests cover only generateFaqPageSchema.
3 SUGGESTION src/lib/schema/faq-page.ts:5 "Rich-result eligibility" rationale is stale post-2026-05-07 FAQ rich-result deprecation. Still useful for AI search citation; refresh the comment.

Specific praise

The schemas-array spread-and-filter pattern in [slug]/page.tsx (...(faqSchema ? [faqSchema] : [])) is a clean way to keep the conditional emission readable — better than mutating the array post-hoc or branching on the JSX side. Worth holding as a template for future optional top-level schemas.

Bottom line

The FAQ schema emission, type additions, and visible Q&A/quote/stat renderers are correct and well-isolated. The blocking concern is the beforeChange hook: as written, it stamps dedicatedDateModified exactly once per post and then permanently freezes it because of the partial-vs-full data semantics in Payload. The schema fallback prevents a null dateModified, but the signal-freshness goal of this PR is undermined. Recommend fixing the hook (and adding tests so the next refactor does not regress) before merging.

@julianken-bot (opus, fresh context, no implementer narrative)

// If the editor manually changed dedicatedDateModified in this save,
// respect that value — do not overwrite.
const editorSetField =
data?.dedicatedDateModified !== originalDoc?.dedicatedDateModified
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

IMPORTANT — the auto-stamp only fires on the first content edit of any post, then is frozen permanently.

data here is a Payload Partial<T> containing only the fields the editor touched in this save (per Payload docs on beforeChange: "On updates, contains only fields being changed"). When the editor edits body but does not touch dedicatedDateModified, data.dedicatedDateModified is undefined. If originalDoc.dedicatedDateModified is already set (e.g. from a prior content edit), this comparison evaluates undefined !== "2026-05-10T..."editorSetField = true → hook returns early without re-stamping.

Concrete walkthrough:

  • First content edit on a post with dedicatedDateModified = null: comparison is undefined !== null → falsy in JS? No — undefined !== null is true strictly, so this returns early too. Actually the field probably starts as undefined on legacy posts, in which case undefined !== undefined is false and stamping proceeds the first time. After it stamps, originalDoc.dedicatedDateModified becomes a string on subsequent loads.
  • Second content edit: comparison is undefined !== "<previous-ISO>"true → returns early. dedicatedDateModified is never updated again, even though body changed.

Net effect: the JSON-LD BlogPosting.dateModified gets stuck on the first stamp and slowly drifts from reality — defeating the citation-freshness signal this PR is trying to build. The ?? fallback in blog-posting.ts papers over the symptom (no null emitted), but the signal quality degrades.

To detect the case "editor explicitly set this field in this save," you need to check whether dedicatedDateModified is present as a key in data (the delta), not whether its value differs from originalDoc. One option:

const editorSetField = data !== undefined && "dedicatedDateModified" in data

This treats "editor touched the field" as the key being present in the delta — regardless of value. Worth confirming against a manual save in the admin UI before shipping.

Related: the MEANINGFUL_FIELDS.some(...) check has the same partial-vs-full confusion — JSON.stringify(data?.body) is undefined when body is unchanged (omitted from delta), JSON.stringify(originalDoc.body) is the full Lexical AST, so they always differ. This makes changed over-eager (false-positive). The over-eagerness happens to push in the right direction (auto-stamp on save) but it means the hook stamps on any save where editorSetField is false, not just body/title/summary edits. Fixing #1 should also fix this check to use the same in-delta semantics.

No tests exist for this hook — see the separate SUGGESTION about coverage.

}

return data
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

SUGGESTION — the 12 new unit tests in this PR are all for generateFaqPageSchema. The beforeChangeDedicatedDateModified hook has more behaviorally subtle semantics (create vs update, partial-vs-full data, editor-override path) and zero coverage. A unit test that mocks data as a Payload Partial<Post> for each path — first stamp, second stamp on body change (catches the bug flagged in the other comment), editor manual override, no-op save with non-content fields changed (e.g. featured flag flip) — would lock down the contract this hook is meant to enforce.

Comment thread src/lib/schema/faq-page.ts Outdated
//
// Generates FAQPage JSON-LD for an agentic design pattern satellite page.
// Emit as a SECOND top-level schema on the satellite page (per Google's
// rich-result guidance) — NOT nested inside the Article schema.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

SUGGESTION — Google deprecated FAQ rich results in Search on 2026-05-07 (the rich result, not the schema itself). The FAQPage JSON-LD is still valuable for AI search engines (Perplexity, ChatGPT, Gemini, Google AI Overviews) which parse it as a primary citation signal. But the comment here and the similar one in RelatedQuestionsBlock.tsx:6-7 cite "rich-result eligibility" as the rationale, which is no longer accurate. Worth refreshing the rationale to "AI-search citation signal" or similar so the next reader does not get confused about why this exists.

See: Schema for Q&A Pages — Google updated guidance

…fied hook

The beforeChange hook compared data.dedicatedDateModified !== originalDoc?.dedicatedDateModified
to detect editor-supplied values, but Payload's `data` on update contains
only fields the editor touched. On normal body edits the field is undefined
in the partial; the comparison evaluates true against any prior stamped
value and early-returns, freezing the timestamp after the first stamp.

Switch to `"dedicatedDateModified" in data` which correctly reads whether
the key is present in the partial. Apply the same key-presence semantics
to the meaningful-content check (body/title/summary) so both branches use
a consistent reading of `data` as a partial. Add 8 unit tests covering
create pass-through, first stamp, second stamp regression, editor override
(value and explicit null), no-op on non-content field changes, and
title/summary-only meaningful edits.

Also refresh stale "FAQ rich-result eligibility" rationale comments in
faq-page.ts and RelatedQuestionsBlock.tsx to "AI-search citation signal"
framing (Google deprecated the FAQ rich result on 2026-05-07; the JSON-LD
remains valuable to Perplexity, ChatGPT search, Gemini, and Google AI
Overviews).

Addresses bot review on #397.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
julianken-bot
julianken-bot previously approved these changes May 17, 2026
Copy link
Copy Markdown
Collaborator

@julianken-bot julianken-bot left a comment

Choose a reason for hiding this comment

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

Verdict: APPROVE (zero findings)

Verification ledger (commands run this turn):

  • gh pr view 397 / gh pr diff 397 — 15 files, +728/-18, head SHA 736c1a8f
  • git checkout pr-397-review — local HEAD matches PR head
  • pnpm typecheck — clean (no output, exit 0)
  • pnpm test:unit --reporter=dot — 545/545 pass (33 files), including the 8 new hook tests and the 12 new FAQ schema tests
  • pnpm lint — 1435 errors, all from .claude/worktrees/.../.next/build/* untracked local build output; zero lint errors in PR-modified files (pre-existing local-clutter only, R7 out-of-scope)
  • R15 mermaid check — 0 blocks in PR body (total:0, ok:true)
  • WebSearch — verified Google's FAQ rich result deprecation on 2026-05-07 is real; the architectural justification for still emitting FAQPage as an AI-search citation signal is sound
  • gh api .../collaborators/julianken-bot/permissionwrite (APPROVE valid)

Findings: none.

R8 second pass. Done with the explicit prior "this contains at least one improvement." Considered: (a) idx as React key in RelatedQuestionsBlock / hostname row in KeyStatisticCallout, (b) redundant as const on "@type": "Question" as const when FaqPageSchema already narrows to literals, (c) the inline comment at [slug]/page.tsx:84 calling FAQPage the "SECOND top-level schema" when the array order puts it third (after Breadcrumb), (d) the hostnameOf fallback silently emitting malformed URLs as both link text and href, (e) duplicated length === 0 guard between RelatedQuestionsBlock and its PatternBody call site. All five are either R5 (bikeshed) or R7 (the URL-foot-gun is consistent with the project's existing handling of author-supplied URLs across realWorldExamples, references, etc. — flagging only here would be inconsistent). Nothing rises to SUGGESTION worth burning a slot on.

What this PR gets right (one specific note, not filler): the dedicatedDateModified hook uses 'key' in data rather than value-vs-originalDoc comparison — exactly the right semantics for Payload's partial-data shape on update, and the regression-named test at tests/unit/lib/hooks/before-change-dedicated-date-modified.test.ts:74 ("second stamp on subsequent body change... regression for partial-data bug") locks that fix in. The fix history (736c1a8) shows the prior bot review caught the value-comparison bug; this revision addresses it cleanly.

Same-tier risk: YES. Implementer was Opus, reviewer is Opus. Per R12 I applied extra skepticism on R8. Findings remain zero after that elevated bar.

Note on PR description accuracy (R5/non-blocking): the body claims pnpm test:unit — 549/549 pass and 537->549 (12 new tests). Actual is 545/545 (8 hook + 12 FAQ + others). Numbers don't match arithmetic; not a code defect, not blocking.

@julianken-bot (Opus 4.7, 1M ctx; fresh-context review)

@julianken
Copy link
Copy Markdown
Owner Author

@Mergifyio queue

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 17, 2026

Merge Queue Status

  • 🟠 Waiting for queue conditions
  • ⏳ Enter queue
  • ⏳ Run checks
  • ⏳ Merge
Required conditions to enter a queue
  • -closed [📌 queue requirement]
  • -conflict [📌 queue requirement]
  • -draft [📌 queue requirement]
  • any of [📌 queue -> configuration change requirements]:
    • -mergify-configuration-changed
    • check-success = Configuration changed
  • any of [🔀 queue conditions]:
    • all of [📌 queue conditions of queue rule default]:
      • #approved-reviews-by >= 1
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • -conflict
      • -draft
      • base = main
      • check-success = Analyze Bundle
      • check-success = CodeQL Analysis
      • check-success = E2E Shard 1/4
      • check-success = E2E Shard 2/4
      • check-success = E2E Shard 3/4
      • check-success = E2E Shard 4/4
      • check-success = ESLint
      • check-success = Next.js Build
      • check-success = TypeScript
      • check-success = Vitest
      • github-review-decision = APPROVED [🛡 GitHub branch protection]
      • any of [🛡 GitHub branch protection]:
        • check-success = ESLint
        • check-neutral = ESLint
        • check-skipped = ESLint
      • any of [🛡 GitHub branch protection]:
        • check-success = TypeScript
        • check-neutral = TypeScript
        • check-skipped = TypeScript
      • any of [🛡 GitHub branch protection]:
        • check-success = Vitest
        • check-neutral = Vitest
        • check-skipped = Vitest
      • any of [🛡 GitHub branch protection]:
        • check-success = Next.js Build
        • check-neutral = Next.js Build
        • check-skipped = Next.js Build
      • any of [🛡 GitHub branch protection]:
        • check-success = Analyze Bundle
        • check-neutral = Analyze Bundle
        • check-skipped = Analyze Bundle
      • any of [🛡 GitHub branch protection]:
        • check-success = CodeQL Analysis
        • check-neutral = CodeQL Analysis
        • check-skipped = CodeQL Analysis
      • any of [🛡 GitHub branch protection]:
        • check-success = E2E Shard 1/4
        • check-neutral = E2E Shard 1/4
        • check-skipped = E2E Shard 1/4
      • any of [🛡 GitHub branch protection]:
        • check-success = E2E Shard 2/4
        • check-neutral = E2E Shard 2/4
        • check-skipped = E2E Shard 2/4
      • any of [🛡 GitHub branch protection]:
        • check-success = E2E Shard 3/4
        • check-neutral = E2E Shard 3/4
        • check-skipped = E2E Shard 3/4
      • any of [🛡 GitHub branch protection]:
        • check-success = E2E Shard 4/4
        • check-neutral = E2E Shard 4/4
        • check-skipped = E2E Shard 4/4

The prior commit added the dedicatedDateModified field to the Posts
collection and regenerated payload-types.ts but did not generate the
corresponding DB migration. CI provisions a fresh Postgres test_db and
runs pnpm seed:test, which SELECTs posts.dedicated_date_modified
against a schema that has no such column -- seeding aborts and all 4
E2E shards die with DrizzleQueryError.

Generated via `pnpm payload migrate:create dedicated_date_modified`.
Trimmed the auto-generated up()/down() body to only the truly new
column -- the same diff also flagged media.lqip / media.preview_color /
media.preview_ascii because the last reconciled JSON snapshot predates
those migrations, but those columns already exist in prod and in any
DB that has run the prior TS migrations. Re-adding them without
IF NOT EXISTS would fail; trimming is correct because the prior
migrations stand on their own.

ALTER TABLE is idempotent (IF NOT EXISTS / IF EXISTS) per the project
convention documented in migrations/README.md and N-1 safe: adding a
nullable column does not break old container SELECTs.

JSON snapshot is kept as-generated so it becomes the new state-of-truth
for future migrate:create diffs.

Addresses E2E failure on #397.
Copy link
Copy Markdown
Collaborator

@julianken-bot julianken-bot left a comment

Choose a reason for hiding this comment

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

Verdict: APPROVE

Verification ledger (commands run this turn, against PR head 506d35f8):

  • gh pr view 397 + gh pr diff 397 — 18 files changed, head SHA matches 506d35f8
  • git checkout 506d35f8 → local HEAD aligned with PR
  • pnpm test:unit545 / 545 pass (33 test files), including 12 new faq-page.test.ts and 8 new before-change-dedicated-date-modified.test.ts
  • rm -rf .next && pnpm typecheckclean (the locally-reported llms-full.txt/route.js error was a stale .next/dev/types/validator.ts artifact, not from this PR; vanishes after cache wipe)
  • pnpm exec eslint <PR-touched files>zero errors on PR-modified files (the 1435 errors visible in pnpm lint are all under untracked .claude/worktrees/.../.next/build/* local Next build output — pre-existing local clutter, R7 out-of-scope, won't reach CI)
  • R15 mermaid render → {total:0, ok:true} (no fenced blocks in PR body; trivially passes)
  • R13 fires on this PR (touches migrations/**, src/payload-types.ts): T1 type contract aligned (dedicatedDateModified?: string | null added to Post), T3 migration coherence checked — ADD COLUMN IF NOT EXISTS is idempotent and N-1 safe per the docstring; JSON snapshot includes the new column plus the previously-unsnapshotted media.lqip/preview_color/preview_ascii columns (added by prior TS migrations but never reconciled in JSON), correctly trimmed from the up()/down() body; T4 spec-vs-impl matches issue #389 acceptance criteria item-for-item
  • gh api .../collaborators/julianken-bot/permissionwrite (APPROVE valid)

Findings:

# Severity File:line Summary
1 SUGGESTION src/components/agentic-patterns/PatternBody.tsx:113 (anchor for a PatternStickyRail.tsx change) JUMP_LINKS doesn't gain entries for the three new optional sections — #common-questions in particular has a visible h2 that readers may want to jump to.

R8 second pass (mandatory, with the explicit prior "this contains at least one improvement"). Considered:

  1. The TOC gap above — the one that landed as a SUGGESTION.
  2. PR description claims pnpm test:unit — 549/549 pass and 537 → 549 (12 new). Actual is 545/545 (likely double-counted the hook tests added in the fix commit). Description-only inaccuracy, R5 territory.
  3. FaqPageSchema lacks optional inLanguage — schema.org-recommended for AI-search citation hygiene but not required; can be added later with no migration cost.
  4. No generateBlogPostingSchema unit test exercising the dedicatedDateModified ?? updatedAt fallback. This file had no unit test before this PR either, so it's a pre-existing gap (R7 out-of-scope).
  5. The schemas-array comment at [slug]/page.tsx:84 calls FAQPage the "SECOND top-level schema" while the array actually puts it third (after Breadcrumb). Bikeshed, R5.

Only (1) survives the second pass as substantive-and-non-bikeshed-and-introduced-by-this-PR.

Same-tier risk: YES (implementer Opus → reviewer Opus). Per R12 I applied elevated skepticism on R8. One finding survived; the rest are bikeshed or pre-existing.

What this PR gets right (specific, not filler):

  • The dedicatedDateModified hook correctly uses 'key' in data rather than value-vs-originalDoc comparison — Payload's BeforeChangeHook.data is typed Partial<T> (verified in node_modules/.../payload/dist/index.bundled.d.ts:574), so key-presence is exactly the right semantics. The regression-named test at before-change-dedicated-date-modified.test.ts:74 ("second stamp on subsequent body change... regression for partial-data bug") locks the fix in.
  • The migration TS file correctly trims to only the new column despite the auto-generated diff also flagging media.lqip/preview_color/preview_ascii; the docstring explains why (those columns already exist in any DB that ran the prior TS migrations) and the JSON snapshot resyncs as the new state-of-truth.
  • The visibility contract between RelatedQuestionsBlock and generateFaqPageSchema is documented in both files and enforced by placing the renderer outside <DisclosureSection> — preventing the AI-search-penalty failure mode of JSON-LD that doesn't match rendered content.

Bottom line. Citation-bait infrastructure is correct and well-isolated. The single SUGGESTION (TOC links for newly-visible sections) is non-blocking; can ship as a follow-up before any pattern is populated with relatedQuestions.

@julianken-bot (Opus 4.7, 1M ctx; fresh-context review against 506d35f8)


{/* 2b. Related questions — optional visible Q&A; unlocks FAQPage JSON-LD */}
{pattern.relatedQuestions && pattern.relatedQuestions.length > 0 && (
<RelatedQuestionsBlock questions={pattern.relatedQuestions} />
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

SUGGESTION — This new visible Common questions section (and its sibling KeyStatisticCallout / ExpertQuoteBlock) is rendered with a scroll-mt-24 anchor (#common-questions), but PatternStickyRail.tsx's JUMP_LINKS array isn't extended to surface them in the "On this page" rail. When relatedQuestions is later populated for a pattern, readers won't be able to jump to it from the rail.

Suggested wiring (in PatternStickyRail.tsx, replacing the static JUMP_LINKS constant with a per-pattern computation):

const jumpLinks = [
  ...(pattern.keyStatistic ? [{ href: "#key-statistic", label: "Key stat" }] : []),
  ...(pattern.expertQuote ? [{ href: "#expert-quote", label: "Quote" }] : []),
  { href: "#decision-matrix", label: "Decision" },
  ...(pattern.relatedQuestions?.length ? [{ href: "#common-questions", label: "Questions" }] : []),
  { href: "#in-the-wild", label: "In the wild" },
  { href: "#implementation-sketch", label: "Sketch" },
  { href: "#references", label: "References" },
  { href: "#background-discussion", label: "Background ↓" },
];

Non-blocking because all 23 patterns are unpopulated for these fields today — but worth wiring before Category I content population so a populated FAQ block doesn't ship without rail navigation.

@julianken
Copy link
Copy Markdown
Owner Author

@Mergifyio queue

@mergify mergify Bot added the queued label May 17, 2026
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 17, 2026

queue

☑️ Command queue ignored because it is already running from a previous command.

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 17, 2026

Merge Queue Status

  • Entered queue2026-05-17 19:06 UTC · Rule: default
  • Checks passed · in-place
  • Merged2026-05-17 19:10 UTC · at c7f7de8fca1fdf4e099e3a0f428c4d1a3c84ebd9 · squash

This pull request spent 4 minutes in the queue, including 3 minutes 32 seconds running CI.

Required conditions to merge
  • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
  • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
  • github-review-decision = APPROVED [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = ESLint
    • check-neutral = ESLint
    • check-skipped = ESLint
  • any of [🛡 GitHub branch protection]:
    • check-success = TypeScript
    • check-neutral = TypeScript
    • check-skipped = TypeScript
  • any of [🛡 GitHub branch protection]:
    • check-success = Vitest
    • check-neutral = Vitest
    • check-skipped = Vitest
  • any of [🛡 GitHub branch protection]:
    • check-success = Next.js Build
    • check-neutral = Next.js Build
    • check-skipped = Next.js Build
  • any of [🛡 GitHub branch protection]:
    • check-success = Analyze Bundle
    • check-neutral = Analyze Bundle
    • check-skipped = Analyze Bundle
  • any of [🛡 GitHub branch protection]:
    • check-success = CodeQL Analysis
    • check-neutral = CodeQL Analysis
    • check-skipped = CodeQL Analysis
  • any of [🛡 GitHub branch protection]:
    • check-success = E2E Shard 1/4
    • check-neutral = E2E Shard 1/4
    • check-skipped = E2E Shard 1/4
  • any of [🛡 GitHub branch protection]:
    • check-success = E2E Shard 2/4
    • check-neutral = E2E Shard 2/4
    • check-skipped = E2E Shard 2/4
  • any of [🛡 GitHub branch protection]:
    • check-success = E2E Shard 3/4
    • check-neutral = E2E Shard 3/4
    • check-skipped = E2E Shard 3/4
  • any of [🛡 GitHub branch protection]:
    • check-success = E2E Shard 4/4
    • check-neutral = E2E Shard 4/4
    • check-skipped = E2E Shard 4/4

@mergify mergify Bot merged commit 073b63d into main May 17, 2026
13 checks passed
@mergify mergify Bot deleted the feat/adp-citation-schema-fields branch May 17, 2026 19:10
@mergify mergify Bot removed the queued label May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-design-patterns Agentic Design Patterns reference page work area:seo SEO + AI-discovery strategy work status:in-review PR open, waiting for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(adp): add relatedQuestions, keyStatistic, expertQuote fields + FAQPage schema

2 participants